python - 将 Ctrl-C 发送到通过 subprocess.Popen 和 ssh 启动的远程进程

标签 python unix ssh popen

如何向 Popen() 对象中的多个 ssh -t 进程发送 Ctrl-C

我有一些 Python 代码可以启动远程主机上的脚本:

# kickoff.py

# i call 'ssh' w/ the '-t' flag so that when i press 'ctrl-c', it get's
# sent to the script on the remote host.  otherwise 'ctrol-c' would just
# kill things on this end, and the script would still be running on the
# remote server
a = subprocess.Popen(['ssh', '-t', 'remote-host', './script.sh', 'a'])
a.communicate()

效果很好,但我需要在远程主机上启动多个脚本:

# kickoff.py

a = subprocess.Popen(['ssh', '-t', 'remote-host', './script.sh', 'a'])
b = subprocess.Popen(['ssh', '-t', 'remote-host', './script.sh', 'b'])
a.communicate()
b.communicate()

这样做的结果是 Ctrl-C 不能可靠地杀死所有东西,而且我的终端总是在之后出现乱码(我必须运行“重置”)。那么,如何在主脚本被杀死时同时杀死两个远程脚本?

注意:我试图避免登录到远程主机,在进程列表中搜索“script.sh”,并向两个进程发送 SIGINT。我只想能够在启动脚本上按 Ctrl-C,然后杀死两个远程进程。不太理想的解决方案可能涉及确定性地查找远程脚本的 PID,但我不知道如何在我当前的设置中执行此操作。

更新:在远程服务器上启动的脚本实际上启动了几个子进程,并且在终止 ssh 的同时确实终止了原始远程脚本(可能是 SIGHUP 的 b/c),子任务不会被杀死。

最佳答案

我能够成功杀死所有子进程的唯一方法是使用 pexpect :

a = pexpect.spawn(['ssh', 'remote-host', './script.sh', 'a'])
a.expect('something')

b = pexpect.spawn(['ssh', 'remote-host', './script.sh', 'b'])
b.expect('something else')

# ...

# to kill ALL of the children
a.sendcontrol('c')
a.close()

b.sendcontrol('c')
b.close()

这个就够靠谱了。我相信其他人早些时候发布了这个答案,但后来删除了答案,所以我将其发布以防其他人好奇。

关于python - 将 Ctrl-C 发送到通过 subprocess.Popen 和 ssh 启动的远程进程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4669204/

相关文章:

python - 来自文本文件的 Argparse 自定义帮助

python - 如何永久设置 QListView 行高

ssh 上的 git 守护进程 - 致命 : protocol error: bad line length character: SSH-

networking - 安装 Docker 后无法 ssh 到机器

go - 私有(private)仓库 - go 1.13 - `go mod ..` 失败 : ping "sum.golang.org/lookup" . 。正在验证包.. 410 消失了

python - 从 python2 转换为 python3 时处理 encode()

python - 如何使用event.type?

linux - 在循环中捕获第一次和第二次出现模式之间的数据

linux - 在 Linux 上安装 Jenkins,执行 shell 命令给出权限被拒绝。

unix - 如何将命令行选项传递给我的 dockerized GoLang 程序?