当我中断 ssh 本身时,如何使 ssh 杀死远程进程?
Posted
技术标签:
【中文标题】当我中断 ssh 本身时,如何使 ssh 杀死远程进程?【英文标题】:How to make ssh to kill remote process when I interrupt ssh itself? 【发布时间】:2010-09-24 19:16:22 【问题描述】:在 bash 脚本中,我通过 ssh 在远程机器上执行命令。如果用户通过按 Ctrl+C 中断脚本,它只会停止脚本 - 甚至不会停止 ssh 客户端。此外,即使我杀死了 ssh 客户端,远程命令仍在运行...
如何让 bash 杀死本地 ssh 客户端和 Crtl+c 上的远程命令调用?
一个简单的脚本:
#/bin/bash
ssh -n -x root@db-host 'mysqldump db' -r file.sql
【问题讨论】:
【参考方案1】:最终我找到了这样的解决方案:
#/bin/bash
ssh -t -x root@db-host 'mysqldump db' -r file.sql
所以 - 我使用“-t”而不是“-n”。 删除“-n”或使用不同于 root 的用户没有帮助。
【讨论】:
【参考方案2】:当您的 ssh 会话结束时,您的 shell 将收到一个 SIGHUP。 (挂机信号)。您需要确保它将其发送到从它启动的所有进程。对于 bash,请尝试 shopt -s huponexit; your_command
。这可能行不通,因为手册页说 huponexit 仅适用于交互式 shell。
我记得用户在我的集群上运行作业时遇到过这种情况,以及他们是否必须使用 nohup(以获得与您想要的相反的行为)但我在 bash 手册页中找不到任何关于是否子进程默认忽略 SIGHUP。希望 huponexit 能解决问题。 (我认为,您可以将该 shopt 放在您的 .bashrc 中,而不是放在命令行中。)
不过,您的ssh -t
应该可以工作,因为当连接关闭时,从终端读取的内容会出现 EOF 或错误,这会导致大多数程序退出。
【讨论】:
【参考方案3】:你知道你传递给 ssh 的选项是做什么的吗?我猜不是。 -n 选项重定向来自 /dev/null 的输入,因此您在远程主机上运行的进程可能没有从 Ctrl-C 看到 SIGINT。
现在,让我们谈谈允许远程 root 登录是多么糟糕的想法:
这是一个非常非常糟糕的主意。查看HOWTO: set up ssh keys 以获取有关如何通过 ssh 安全地管理远程进程执行的一些建议。如果您需要远程运行具有特权的东西,您可能需要一个解决方案,该解决方案涉及一个带有嵌入式命令的 ssh 公钥和一个由 sudo 提供的以 root 身份运行的脚本。
【讨论】:
【参考方案4】:trap "some_command" SIGINT
当您按下 Ctrl+C 时,将在本地执行 some_command
。 help trap
会告诉你它的其他选项。
关于ssh
问题,我对ssh 了解不多。也许你可以让它调用ssh -n -x root@db-host 'killall mysqldump'
而不是some_command
来杀死远程命令?
【讨论】:
【参考方案5】:如果您不想要求使用“ssh -t”(对于像我这样健忘的人)怎么办?
我无意中查看了父 PID,因为启动会话中的 CTRL/C 会导致远程进程上的 ssh 启动进程退出,尽管其子进程仍在继续。例如,这是我在远程服务器上的脚本。
#!/bin/bash
Answer=(Alive Dead)
Index=0
while [ $Index -eq 0 ]; do
if ! kill -0 $PPID 2> /dev/null ; then Index=1; fi
echo "Parent PID $PPID is $Answer[$Index] at $(date +%Y%m%d%H%M%S%Z)" > ~/NowTime.txt
sleep 1
done
然后我用“ssh remote_server ./test_script.sh”调用它 远程服务器上的“watch cat ~/NowTime.txt”显示文件中的时间戳增加并声明父进程处于活动状态;一旦我在启动过程中按下 CTRL/C,远程服务器上的脚本就会注意到它的父进程已经死亡,并且脚本退出。
【讨论】:
以上是关于当我中断 ssh 本身时,如何使 ssh 杀死远程进程?的主要内容,如果未能解决你的问题,请参考以下文章
当我通过 Git Bash 中的 ssh 在远程 Linux 机器上运行命令时,如何将文件的内容直接复制到我的 Windows 剪贴板中?