使用python subprocess.Popen

时间:2015-11-24 00:54:47

标签: python ssh subprocess popen zombie-process

我有一个使用2台不同机器运行测试用例的脚本。测试需要在机器1上运行命令之前在机器1上运行一些命令,然后机器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脚本启动的日志记录脚本,但正如我所说,当我查看所有正在运行的进程时,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脚本会挂起等待将std输出放入结果中。这绝不会发生。我的prerun脚本确实有std输出,但我认为它不能收集它,因为它可能是一种守护进程?我不太了解prerun脚本。

1 个答案:

答案 0 :(得分:0)

删除管道对我的方案有用。现在,我从机器上的远程机器获得所有输出,我开始测试,一切都优雅地结束。顺便说一下,我发现默认情况下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"])