使用 python subprocess.Popen 的僵尸 ssh 进程

Zombie ssh process using python subprocess.Popen

我有一个脚本,它 运行 是一个使用 2 台不同机器的测试用例。测试需要机器 1 上的一些命令 运行 在机器 2 上的命令 运行 之前,然后机器 1 将数据发送到机器 2。目标是能够 运行 测试来自机器,所以我想我会 ssh 到机器 1 并在那里执行命令,然后 ssh 到机器 2 并在那里执行命令......我试图避免 paramiko 因为我不想要额外的依赖,所以我发现这段漂亮的代码可以完成工作:

def executeRemoteCommand(host, command):
  ssh = subprocess.Popen(["ssh", "%s" % host, command],
                         shell=False,
                         stdout=subprocess.PIPE,
                         stderr=subprocess.PIPE)

这是我正在做的一个例子:

executeRemoteCommand(user@machine1, "cd /dcd-netapp1/test/test-priority_v6; ./prerun")
time.sleep(30)  
executeRemoteCommand(user@machine2, "cd /dcd-netapp1/test/test-priority-v6; ./run")
time.sleep(1800)
executeRemoteCommand(user@machine1, "cd /dcd-netapp1/test/test-priority-v6; ./postrun")
executeRemoteCommand(user@machine2, "cd /dcd-netapp1/test/test-priority-v6; ./graph_results")

问题是我的 prerun ssh 会话没有终止。 postrun 脚本负责杀死使用 prerun 脚本启动的日志记录脚本,但正如我所说,当我查看所有 [=35] 时,测试结束后 ssh 会话显示良好=]宁进程 ps -ef | grep ssh

对于一些额外的信息,我曾经在 executeRemoteCommand 函数中包含以下代码:

result = ssh.stdout.readlines()
if result == []:
  error = ssh.stderr.readlines()
  print >>sys.stderr, "ERROR: %s" % error
else:
  print result

我把它注释掉了,因为 prerun 脚本会挂起,等待将标准输出放入结果中。这永远不会发生。我的 prerun 脚本确实有标准输出,但我认为它无法收集它,因为它可能是一种守护进程?我不太了解 prerun 脚本。

移除管道对我的方案有效。现在,我从我开始测试的机器上的远程机器上获得了所有输出,一切都正常结束。顺便说一下,我发现 shell=False 默认情况下是假的,所以它是不必要的, %s % host 字符串替换也是如此。这是与我的确切问题相关的内容:

def executeRemoteCommand(host, command):
  ssh = subprocess.Popen(["ssh", host, command])

由于函数现在超级简化,我更进一步,认为如果我完全摆脱函数并直接使用 Popen,测试将更容易阅读:

subprocess.Popen(["ssh", user@machine1, "cd /dcd-netapp1/test/test-priority-v6; ./prerun"])
time.sleep(5)
subprocess.Popen(["ssh", user@machine2, "cd /dcd-netapp1/test/test-priority-v6; ./run"])
time.sleep(1800)
subprocess.Popen(["ssh", user@machine1, "cd /dcd-netapp1/test/test-priority-v6; ./postrun"])
subprocess.Popen(["ssh", user@machine1, "cd /dcd-netapp1/test/test-priority-v6; ./graph_results"])