bash:向while循环发送控制信号?

时间:2014-05-13 22:16:02

标签: bash

简单的bash行:

for h in $(cat /tmp/hosts); do ssh $h; done

如果我输入Ctrl-C,它会按预期退出for循环。但我想要一种发送信号的方法,该信号只会从当前的ssh行中断开,然后继续循环中的下一次迭代。这在我不想或不能登录特定主机的情况下非常有用,但我想立即与文件中的其他人一起进行操作。有没有办法指定一个可以用这种方式捕获的控制字符?

解答: 我想到了。

for h in $(cat /tmp/hosts); do trap 'continue' 3; ssh $h; done

信号3对应Ctrl-\。因此,要杀死当前的ssh命令(在您登录主机之前,如果您已经登录它将无法工作)并转到循环中的下一个,请键入{{ 1}}。终止整个"脚本"输入Ctrl-\。有效;清洁;完全符合我的需要。

2 个答案:

答案 0 :(得分:1)

按ctrl + c时,默认情况下应该发生这种情况。但是我发现你的命令中有一些错误。

首先,while循环和ssh命令都是从同一个管道读取的。这可能会导致意外结果,因为第一个ssh命令会读取所有主机名,while命令会看到EOF,当它应该找到更多主机名时。

该问题的通常解决方案是使用-n命令的ssh标志。

此外,ssh不是tty时,如果没有命令运行stdin,则不建议使用。我想你真的想在ssh命令中为远程系统添加一个命令。

命令的外观如下:

while read h; do ssh -n "$h" 'sleep 10'; done </tmp/hosts

除了按ctrl-c之外,您还可以从其他shell中删除ssh命令。在另一个shell中,您可以输入ps -fC ssh来获取正在运行的ssh进程的列表,然后使用kill后跟pid来杀死其中一个进程。

答案 1 :(得分:0)

我知道这不是您正在寻找的策略,但有一些替代方案不涉及从交互式shell中窃取信号:

  • ssh有&#34;终止&#34;用于此目的的转义序列。按Enter键后立即键入以下键(但仅限于您准备丢失的会话):~.请记住,这会杀死嵌套的ssh命令的最顶层;如果初始连接不是通过ssh命令,则对远程主机更有效。 (正如你的评论和downvote暗示,你正在筑巢)
  • Ctrl-D在空提示符下是一个优雅的shell挂断。为您省去键入exitlogout的麻烦,并且非常友好地建议您在后台运行程序。如果确实需要突破ssh,请坚持使用~.