26

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

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

一个简单的脚本:

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

5 回答 5

24

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

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

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

于 2008-12-03T13:17:34.170 回答
4

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

我记得用户在我的集群上运行作业时遇到了这个问题,以及他们是否必须使用 nohup (以获得与您想要的相反的行为)但我在 bash 手册页中找不到任何关于子进程是否忽略的内容SIGHUP 默认情况下。希望 huponexit 能解决问题。(我认为,您可以将该 shopt 放在您的 .bashrc 中,而不是放在命令行中。)

但是,您ssh -t应该可以工作,因为当连接关闭时,从终端读取的内容会出现 EOF 或错误,这会使大多数程序退出。

于 2009-12-09T20:32:28.647 回答
2

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

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

这是一个非常非常糟糕的主意。查看HOWTO:设置 ssh 密钥,了解如何通过 ssh 安全地管理远程进程执行的一些建议。如果您需要远程运行具有特权的东西,您可能需要一个解决方案,该解决方案涉及一个带有嵌入式命令的 ssh 公钥和一个由 sudo 提供的以 root 身份运行的脚本。

于 2008-12-02T15:53:07.040 回答
1
trap "some_command" SIGINT

some_command当您按 Ctrl+C 时将在本地执行。help trap会告诉你它的其他选择。

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

于 2008-12-01T18:05:52.123 回答
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,远程服务器上的脚本就会注意到它的父进程已经死亡,并且脚本退出。

于 2020-08-07T03:07:48.253 回答