远程进程完成的通知(但没有电子邮件)

远程进程完成的通知(但没有电子邮件)

我正在使用 OpenSSH 连接到 Linux 服务器,在该服务器上有一个tmux会话,我在其中执行某些需要很长时间的编译工作。现在,一旦某个需要很长时间的命令最终完成,我希望立即在我的 Linux 客户端(我连接的计算机)上收到通知。

在本地,我知道如何使用弹出窗口、播放某些内容…… (1)、(2)通过运行某个命令来获得通知。现在我需要远程做同样的事情。一个完美的解决方案是某种反馈渠道,ssh但我不知道有任何这样的功能。

并且请不要使用(3)中建议的基于电子邮件的解决方案。我已经收到了太多的工作电子邮件,我正在尝试减少电子邮件的数量,只是为了确认,而不是为了阅读、存储、转发或回复(为此,我什至创建了一个单独的电子邮件帐户,我收不到实时通知)。


  1. https://superuser.com/questions/345447/how-can-i-trigger-a-notification-when-a-job-process-ends
  2. https://askubuntu.com/questions/277215/make-a-sound-once-process-is-complete
  3. 运行进程完成时发出警报

答案1

对于仍然存在 ssh 连接的情况,可以使用port forwarding。我将把两台机器称为laptopserver,其中后者正在执行长时间运行的作业。我认为这样做的主要优点是针对临时设置,例如从咖啡店的笔记本电脑进行连接。对于该用例,您将在 NAT 之后运行,可能无法使用 PNP 打开端口。它通常不需要在服务器上安装任何东西。如果这不适用,请遵循在笔记本电脑上设置 ssh 服务的建议。

在笔记本电脑上调用 ssh,并要求其将远程 tcp 端口 4000 转发到本地端口 5000。实际上,您会在两端使用相同的端口号,我使用不同的端口号,以便更清楚地了解发生了什么。这里我使用openssh命令行

ssh -R 4000:127.0.0.1:5000 username@server

连接到 tmux,启动作业,安排长时间运行的作业完成时写入端口 4000。

(long_running job with params ; echo "$?" > /dev/tcp/127.0.0.1/4000) &

如果你没有 /dev/tcp 并且它不是由 shell 模拟的,那么你可以使用类似的东西echo "$?" | netcat 127.0.0.1 4000

同时,在笔记本电脑上侦听端口 5000 上的连接,可能是在不同的窗口中。

netcat -l -p 5000; do_something_to_alert_the_local_user.

netcat 将阻止等待服务器连接到端口 4000,该连接将通过加密的 ssh 隧道转发到端口 5000。在 echo 结束时连接关闭后,本地netcat将退出,并且 do_something_to_alert_the_local_user 将运行。

答案2

最简单的解决方案是使用 tmux 退出,通过发出 tmux 分离来关闭 ssh 连接,然后发送通知,然后重新连接并附加回 tmux。例如使用脚本

ssh -t remote tmux
notify-send done
ssh -t remote tmux attach

您运行 tmux,并开始长时间运行的命令,然后提前输入命令

tmux detach

当长命令完成时它将运行。这将关闭 tmux,关闭 ssh,通知发送将显示您的桌面消息。新的 ssh 将准确地重新连接到您上次中断的位置。

答案3

跟进@icarus的解决方案,改用这个命令:

echo "$?" | netcat 127.0.0.1 4000 -q 0

否则netcat将无限期地等待并且永远不会关闭连接。另外,如果你想从 ssh 主机传输数据到你的本地主机,你可以按如下方式监听:

SUM=$(netcat -l -p 5000); notify-send $SUM

答案4

如果您在客户端上运行 OpenSSH 服务器,则可以将其配置为强制针对特定密钥运行特定命令。如果操作正确,此密钥只能用于触发此通知,而不能用于任何明显邪恶的事情。

为了使事情不那么混乱(因为在这种情况下,我们双方都有客户端或服务器的操作),我将调用本地计算机,即连接到远程服务器以启动长期任务的客户端,爱丽丝鲍勃然后服务器将在其中启动编译任务,然后在该服务器上通知 Alice 任务完成情况。

为此,您基本上只需使用生成密钥ssh-keygen -f notif_key,然后将公钥 ( notif_key.pub) 添加到 Alice 中的单独行中.ssh/authorized_keys,但前面加上:

command="/path/to/notifier.sh \"$SSH_ORIGINAL_COMMAND\"",no-port-forwarding,no-x11-forwarding,no-agent-forwarding ssh-rsa …

ssh-rsa …代表公钥。)

notifier.sh是 Alice 这边的一个脚本,然后它调用通知命令(当然,如果可能的话,您可以立即开始,只需注意整行都是在 shell 中执行的)。

然后,在 Bob 一侧,您可以使用 触发 Alice 一侧的通知ssh,因此您可以在会话中在 Bob 上运行tmux

time-consuming-command; ssh -i notif_key user@alice_pc foobar

就是这样!

顺便说一句,$SSH_ORIGINAL_COMMAND是该命令的所有额外命令行的占位符,ssh然后该命令将被转发到强制命令。通过这种方式,您可以自定义来自 Bob 的特定通知,例如,当您同时以这种方式运行多个任务时。

notifier.sh考虑到这一点的示例:

#!/bin/sh
some-notification-command --message "Task '$*' is done!"
echo 'Note to Bob: Alice has been notified.'

总而言之,这个解决方案远非最佳。它需要客户端上有一个 OpenSSH 服务器,并且配置起来相当麻烦。我希望存在更好的解决方案。

相关内容