当我中断 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_commandhelp 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 杀死远程进程?的主要内容,如果未能解决你的问题,请参考以下文章

当我已经 ssh 进入远程机器时,如何 scp 回到本地?

cygwin ssh 在退出时给出“被信号 1 杀死”

使用 SSH 在远程服务器上启动后台进程,并退出会话

如何在 ssh / 远程 bash 命令中转义单引号字符?

当我通过 Git Bash 中的 ssh 在远程 Linux 机器上运行命令时,如何将文件的内容直接复制到我的 Windows 剪贴板中?

如何在另一台远程服务器上使用我的 SSH 密钥进行 Git?