当我中断ssh本身时如何使ssh杀死远程进程?

时间:2008-12-01 17:54:06

标签: bash ssh

在bash脚本中,我通过ssh在远程机器上执行命令。如果用户通过按Ctrl + C中断脚本,它只会停止脚本 - 甚至不会停止ssh客户端。此外,即使我杀死ssh客户端,远程命令仍在运行......

如何使bash在Crtl + c上杀死本地ssh客户端和远程命令调用?

一个简单的脚本:

#/bin/bash
ssh -n -x root@db-host 'mysqldump db' -r file.sql

5 个答案:

答案 0 :(得分:19)

最终我找到了这样的解决方案:

#/bin/bash
ssh -t -x root@db-host 'mysqldump db' -r file.sql

所以 - 我使用'-t'而不是'-n'。 删除'-n'或使用不同于root的用户无济于事。

答案 1 :(得分:3)

当你的ssh会话结束时,你的shell将获得一个SIGHUP。 (挂断信号)。您需要确保将其发送到从其启动的所有进程。对于bash,请尝试shopt -s huponexit; your_command。这可能不起作用,因为手册页说huponexit仅适用于交互式shell。

我记得在我的群集上运行作业的用户遇到此问题,以及他们是否必须使用nohup(以获得您想要的相反行为)但我在bash手册页中找不到任何关于是否子进程默认忽略SIGHUP。希望huponexit会做到这一点。 (你可以把这个shopt放在你的.bashrc中,而不是在命令行上。)

但是,ssh -t应该可以正常工作,因为当连接关闭时,从终端读取将获得EOF或错误,这使大多数程序退出。

答案 2 :(得分:2)

你知道你传递给ssh的选项是什么吗?我猜不是。 -n选项重定向来自/ dev / null的输入,因此您在远程主机上运行的进程可能无法从Ctrl-C看到SIGINT。

现在,让我们谈谈允许远程root登录的想法有多糟糕:

这是一个非常非常糟糕的主意。请查看HOWTO: set up ssh keys,了解如何通过ssh安全地管理远程进程执行的一些建议。如果您需要远程运行具有权限的内容,您可能需要一个解决方案,该解决方案涉及带有嵌入式命令的ssh公钥和以root用户身份运行sudo的脚本。

答案 3 :(得分:1)

trap "some_command" SIGINT
按Ctrl + C时,

将在本地执行some_commandhelp trap会告诉您其他选项。

关于ssh问题,我对ssh了解不多。也许你可以调用ssh -n -x root@db-host 'killall mysqldump'而不是some_command来杀死远程命令?

答案 4 :(得分:0)

如果您不想使用“ 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组合键后,远程服务器上的脚本会注意到其父进程已死亡,并且脚本退出。