SSH를 통해 긴 작업이 완료되면 경고를 보내는 방법은 무엇입니까?

SSH를 통해 긴 작업이 완료되면 경고를 보내는 방법은 무엇입니까?

notify-send내 데스크탑은 Ubuntu이고 데스크탑에 경고를 표시하는 편리한 프로그램이 있습니다 . 또한 다음과 같은 편리한 별칭이 내장되어 있습니다.

$ type alert
alert is aliased to `notify-send --urgency=low -i "$([ $? = 0 ] && echo terminal || echo error)" "$(history|tail -n1|sed -e 's/^\s*[0-9]\+\s*//;s/[;&|]\s*alert$//')"'

즉, 를 실행하고 very-long-running-command; alert, 터미널을 백그라운드에서 실행하고, 작업이 완료되면 알림을 받을 수 있습니다.

SSH를 통해 CentOS 서버에 연결하면 상황이 조금 더 까다로워집니다. 한 가지 방법은 다음과 같습니다.

localhost$ ssh [email protected]; alert
example.net$ very-long-running-command; exit

이것은 어느 정도 작동하지만 각 명령 후에 종료하는 것은 일반적으로 내가 원하는 것이 아닙니다.

내 컴퓨터에는 스피커가 없습니다. 경고음이 울릴 수 있습니다.

답변1

제가 생각할 수 있는 가장 간단한 방법은 두 번째 SSH 세션을 사용하여 명명된 FIFO를 전달하는 것입니다. 나는 tmp/당신의 홈 디렉토리에 하나가 있다고 가정합니다. FIFO를 원하는 곳에 자유롭게 보관하십시오.

local$ ssh me@remotehost 'mkfifo ~/tmp/alert_fifo ; while cat ~/tmp/alert_fifo ; do : ; done' | \
    while read icon_name text ; do
        notify_send --urgency=low -i "$icon_name" "$text"
    done &

그런 다음 실제 작업을 수행하기 위해 두 번째 SSH 세션을 여는 동안 백그라운드에서 실행되도록 둘 수 있습니다.

local$ ssh me@remotehost
remote$ alias remote_alert='echo ... >~/tmp/alert_fifo'
remote$ long_running_command; remote_alert

...여기서 remote_alert수정된 alert별칭 은 notify_send --urgency=low -iFIFO에 내용을 반영하여 대체됩니다.

이는 원격 시스템에서 최소한의 도구 세트(ssh 및 표준 POSIX 유틸리티만 사용)를 사용합니다. 그러나 FIFO를 사용하면 리더를 실행하는 것을 잊어버리면(또는 리더가 죽으면) 작성자가 중단됩니다. 따라서 시간이 좀 있으면 socat좀 더 관대하게 만들 수 있습니다.

local$ ssh me@remotehost 'socat UNIX-RECV:~/tmp/alert_socket -' | \
    while read ...
        ...
    done &

local$ ssh me@remotehost
remote$ alias remote_alert='echo ... | socat - UNIX-SEND:~/tmp/alert_socket'

답변2

터미널 에뮬레이터 터미네이터를 설치할 수 있습니다. 그런 다음 터미널을 마우스 오른쪽 버튼으로 클릭하고 "활동 모니터링" 또는 "무음 모니터링"을 선택하십시오. 터미널에서 출력이 생성되거나 일정 기간 동안 출력이 생성되지 않으면 각각 알려줍니다. 명령이 출력을 생성하지 않으면 ; echo "{!1} Done!"명령 끝에 다음과 같은 내용을 추가할 수 있습니다. 특정 키워드가 출력에 나타날 때마다 알려주는 종결자 확장을 만들었습니다. 비밀번호를 잊어버렸는데도요. 기존 확장을 기반으로 구축하고 Python에 능숙하다면 프로그래밍은 매우 간단합니다. 추가 보너스는 SSH 연결 체인을 통해 터널링하더라도 동일하게 작동한다는 것입니다.

답변3

이것은 답변의 일부입니다. 바라보다D-Bus 인증 및 승인내가 대기하는 지점까지.

notify-send문자 보내D 버스. 최신 데스크탑 환경은 세션당 D-Bus 버스를 시작하고 일반적으로 환경 변수를 설정하여 세션의 프로그램이 올바른 버스를 찾도록 조정합니다 DBUS_SESSION_BUS_ADDRESS. D-Bus는 추상 소켓, Unix 소켓 및 TCP를 포함하여 메시지를 중앙 집중화하고 전달하는 데몬에 연결하는 다양한 방법을 지원합니다.

OpenSSH ≥6.7은 Unix 소켓을 전달할 수 있습니다., 그러나 제가 글을 쓰는 동안 이러한 최신 버전을 실행하는 시스템은 거의 없습니다.

당신은 할 수TCP를 수신하는 D-Bus 데몬 실행(TCP 및 Unix 소켓과 같은 여러 주소에서 수신 대기하도록 할 수 있습니다.) dbus-daemon세션 시작 스크립트가 사용자가 영향을 미칠 수 없는 방식으로 시작 되면 예약하기 어려울 수 있습니다.

다음 도구를 사용하여 TCP를 통해 D-Bus 추상 소켓 또는 명명된 Unix 소켓을 전달할 수 있습니다.인터넷 고양이또는소캇. 이는 TCP 포트 8004에서 전달을 설정하는 개념 증명 스크립트입니다.

#!/bin/sh
case $DBUS_SESSION_BUS_ADDRESS in
  '') echo 1>&2 "No local D-Bus instance";;
  unix:abstract=*,guid=*)
    guid=${DBUS_SESSION_BUS_ADDRESS##*[:,]guid=}
    guid=${guid%%,*}
    socket=${DBUS_SESSION_BUS_ADDRESS##*[:,]abstract=}
    socket=ABSTRACT-CONNECT:${socket%%,*}
    ;;
  unix:path=*,guid=*)
    guid=${DBUS_SESSION_BUS_ADDRESS##*[:,]guid=}
    guid=${guid%%,*}
    socket=${DBUS_SESSION_BUS_ADDRESS##*[:,]path=}
    socket=UNIX-CONNECT:${socket%%,*}
    ;;
  *) echo 1>&2 "Unsupported DBUS_SESSION_BUS_ADDRESS";;
esac
socat "TCP-LISTEN:8004,reuseaddr,fork,range=127.0.0.1/32" "$socket"

이제 SSH를 통해 이 TCP 연결을 전달할 수 있습니다.

ssh -R 8004:localhost:8004 [email protected]
[email protected]$ export DBUS_SESSION_BUS_ADDRESS=tcp:host=127.0.0.1,port=8004

한 가지 더 해야 할 일은 인증 쿠키를 원격 컴퓨터에 복사하는 것입니다.

rsync -a .dbus-keyrings/org_freedesktop_general [email protected]:.dbus-keyrings/org_freedesktop_general

X11 쿠키와 달리 D-Bus 쿠키는 서버 수명 동안 변경될 수 있습니다. 사실 내 실험에서는 불규칙한 간격으로, 때로는 단지 몇 분 후에만 변화하는 것처럼 보였습니다.

내가 아는 한, 최신 버전의 Gnome 라이브러리만이 쿠키 파일을 읽습니다. notify-sendGnome 3.14가 포함된 FreeBSD 10.1에서는 읽을 수 있지만 Gnome 3.4가 포함된 Debian wheezy에서는 읽을 수 없습니다.

관련 정보