Como posso alertar sobre a conclusão de uma tarefa longa sobre o ssh?

3

Meu desktop é o Ubuntu, que possui o programa prático notify-send , que exibe um alerta na área de trabalho. Ele também possui o seguinte alias útil incorporado:

$ 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$//')"'

Isso significa que você pode executar very-long-running-command; alert , deixar o terminal em execução em segundo plano e receber uma notificação quando a tarefa estiver concluída.

Quando você está em um servidor do CentOS por meio do ssh, as coisas são um pouco mais complicadas. Aqui está uma maneira de fazer isso:

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

Isso funciona, depois de certo modo, mas sair depois de cada comando geralmente não é o que eu quero fazer.

Meu computador não tem alto-falantes. Pode bipar.

    
por TRiG 03.04.2015 / 16:58

3 respostas

3

A coisa mais simples que posso imaginar aqui é usar uma segunda sessão SSH para encaminhar um FIFO nomeado. Suponho que você tenha um tmp/ em seu diretório inicial. sinta-se livre para manter o FIFO onde quiser.

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 &

Depois, você pode deixar isso ser executado em segundo plano enquanto você abre uma segunda sessão SSH para fazer seu trabalho real:

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

... onde remote_alert é um alias de alert modificado com notify_send --urgency=low -i substituído por itens de eco no FIFO.

Isso funcionará com um conjunto mínimo de ferramentas na máquina remota: somente utilitários ssh e POSIX padrão. No entanto, com um FIFO, se você esquecer de executar seu leitor (ou seu leitor morre), seu gravador irá travar. Então, se você tiver socat disponível, você pode tornar isso um pouco mais indulgente:

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'
    
por 05.05.2015 / 07:45
0

Esta é uma resposta parcial. Veja autenticação e autorização do D-Bus para pontos em que estou preso.

notify-send envia uma mensagem por D-Bus . Ambientes de área de trabalho modernos iniciam um barramento D-Bus por sessão e organizam os programas na sessão para encontrar o barramento correto, geralmente configurando a variável de ambiente DBUS_SESSION_BUS_ADDRESS . O D-Bus suporta várias maneiras de se conectar ao daemon que centraliza e despacha mensagens, incluindo soquetes abstratos, soquetes unix e TCP.

OpenSSH ≥6.7 pode encaminhar sockets Unix , mas enquanto escrevo, poucos sistemas estão rodando uma versão tão recente.

Você pode executar um daemon D-Bus que escuta TCP (você pode faça ouvir em vários endereços, por exemplo, TCP e um socket Unix). Isso pode ser difícil de organizar se dbus-daemon for iniciado pelos scripts de inicialização da sua sessão de uma forma que você não pode influenciar.

Você pode encaminhar o soquete abstrato do D-Bus ou denominado soquete Unix sobre TCP com uma ferramenta como netcat ou < href="http://www.dest-unreach.org/socat/"> socat . Aqui está um script de prova de conceito que configura o encaminhamento na porta 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"

Você agora pode encaminhar essa conexão TCP por SSH.

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

Você precisa fazer mais uma coisa: copiar o cookie de autorização para a máquina remota.

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

Tenha em atenção que, ao contrário do cookie X11, o cookie D-Bus pode mudar durante o tempo de vida do servidor. De fato, em meus experimentos, pareceu mudar em intervalos irregulares, às vezes depois de apenas alguns minutos.

Apenas versões recentes de bibliotecas do Gnome lêem o arquivo de cookies, até onde eu sei. notify-send lê-lo no FreeBSD 10.1 com o Gnome 3.14 mas não no Debian wheezy com o Gnome 3.4.

    
por 04.04.2015 / 03:36
0

Você pode instalar o terminador do emulador de terminal. Em seguida, clique com o botão direito no seu terminal e selecione "watch for activity" ou "watch for silence". Isso notificará você assim que a saída for produzida no terminal ou nenhuma saída for produzida por algum tempo, respectivamente. Se o seu comando não produzir saída, basta anexar algo como ; echo "{!1} Done!" ao final do comando. Eu tinha construído uma extensão para o terminador que me notifica toda vez que uma palavra-chave específica na saída ocorreu. Embora eu tenha perdido o código. A programação é bastante direta se você construiu sobre as extensões existentes e é versado em Python. O benefício adicional é que ele funciona da mesma forma, mesmo que você faça um túnel através de uma cadeia de conexões ssh.

    
por 16.02.2018 / 10:58