gpt4 book ai didi

bash - 使用 bash 通过 ssh 启动一个进程,然后在 sigint 上终止它

转载 作者:行者123 更新时间:2023-11-29 08:49:04 28 4
gpt4 key购买 nike

我想使用 ssh 在不同的机器上启动几个作业。如果用户随后中断主脚本,我想优雅地关闭所有作业。

这是我正在尝试做的一个简短示例:

#!/bin/bash
trap "aborted" SIGINT SIGTERM
aborted() {
kill -SIGTERM $bash2_pid
exit
}

ssh -t remote_machine /foo/bar.sh &
bash2_pid=$!
wait

但是 bar.sh 进程仍在远程机器上运行。如果我在终端窗口中执行相同的命令,它会关闭远程主机上的进程。

当我运行 bash 脚本时,有没有一种简单的方法可以实现这一点?或者我是否需要让它登录到远程计算机,找到正确的进程并以这种方式终止它?

编辑:似乎我必须选择选项 B,通过另一个 ssh 连接终止远程脚本

所以不,我想知道如何获取 remotepid?我已经尝试了一些类似的东西:

remote_pid=$(ssh remote_machine '{ /foo/bar.sh & } ; echo $!')

这不起作用,因为它会阻塞。

如何等待变量打印然后“释放”子进程?

最佳答案

将清理工作由启动进程的 ssh 管理绝对比稍后使用第二个 ssh session 进行清理要好。

当 ssh 连接到您的终端时;它表现得很好。但是,将它从您的终端中分离出来(正如您所注意到的)发送信号或管理远程进程变得很痛苦。您可以关闭链接,但不能关闭远程进程。

这给您留下了一个选择:使用链接作为远程进程获得需要关闭的通知的一种方式。最简洁的方法是使用阻塞 I/O。从 ssh 以及您希望进程关闭的时间进行远程读取输入;向它发送一些数据,以便远程的读取操作解除阻塞,它可以继续进行清理:

command & read; kill $!

这就是我们想要在远程运行的。我们调用我们想要远程运行的命令;我们读取一行文本( block 直到我们收到一行),当我们完成后,发出终止命令的信号。

要将信号从我们的本地脚本发送到远程,我们现在需要做的就是向它发送一行文本。不幸的是,Bash 在这里没有给你很多好的选择。至少,如果您想与 bash < 4.0 兼容,则不会。

在 bash 4 中我们可以使用协同进程:

coproc ssh user@host 'command & read; kill $!'
trap 'echo >&"${COPROC[1]}"' EXIT
...

现在,当本地脚本退出时(不要陷入 INTTERM 等。只需 EXIT),它会发送一个新的COPROC 数组第二个元素中的文件行。该文件是一个连接到 sshstdin 的管道,有效地将我们的线路路由到 ssh。远程命令读取行,结束 readkill 命令。

在 bash 4 之前,事情变得有点困难,因为我们没有协同进程。在那种情况下,我们需要自己做管道:

mkfifo /tmp/mysshcommand
ssh user@host 'command & read; kill $!' < /tmp/mysshcommand &
trap 'echo > /tmp/mysshcommand; rm /tmp/mysshcommand' EXIT

这应该适用于几乎任何 bash 版本。

关于bash - 使用 bash 通过 ssh 启动一个进程,然后在 sigint 上终止它,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3235180/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com