令人惊讶的是,通过 SSH 在远程启动一个长时间运行的进程,同时保持对客户端进程的控制以便稍后将其终止,这似乎相当复杂。简单地组合
nohup
、<process> &
和 echo "$!"
没有帮助。
对于我的用例,客户端上的 SSH 连接是非阻塞的并且在后台运行至关重要,因为逻辑是更大脚本的一部分,其中最终清理应该终止远程进程。由于执行
killall <name>
太过分了,所以 kill $PID
绝对是更好的选择。我尝试了各种策略,但没有成功。
这大致翻译为
[client]$ ssh user@host "long_running_task" &
[client]$ export SSH_SESSION_PID=$!
此策略的问题在于
[client]$ kill -INT $SSH_SESSION_PID
只会杀死客户端上的 SSH 进程。这不会传播到远程进程。通过查看遥控器上的htop
,我可以观察到远程进程一直在运行。
nohup
并在客户端保存远程PID这大致翻译为:
REMOTE_PID=$(ssh user@host "nohup long_running_task & echo $\!")
需要放在后台
但是,这会一直运行直到任务完成。不存在短路现象!并且以下尝试(伪语法)都无法修复它:
REMOTE_PID=$(ssh user@host "nohup long_running_task & echo $\!") &
REMOTE_PID=$(ssh user@host "nohup long_running_task & echo $\!" &)
因此,目前还不清楚通过 SSH 控制长时间运行的进程并最终终止它的最佳实践是什么。
您需要单引号:
REMOTE_PID=$(ssh orac 'nohup long_running_task >& /tmp/long_running_task.log & echo $!')