调试subprocess.Popen调用

时间:2010-02-05 10:05:28

标签: python subprocess

我过去一直在成功使用subprocess.Popen,当用python脚本包装二进制文件来格式化参数/自定义等...

开发第n个包装器,我像往常一样......但没有任何反应。

这是小代码:

print command
p = subprocess.Popen(command, shell = True)
result = p.communicate()[0]
print vars(p)
return result

这是输出:

/usr/bin/sh /tmp/run/launch.sh
{'_child_created': True, 'returncode': 0, 'stdout': None, 'stdin': None, 'pid': 21650, 'stderr': None, 'universal_newlines': False}

正如您所看到的,目标是创建一个shell脚本来设置我需要的所有内容,然后执行它。我更喜欢使用真正的python代码,但不幸的是launch.sh调用我不想尝试复制的第三方shell脚本(虽然我一直坚持使用python api超过一年)。

问题在于:

  • shell脚本未执行(它应该生成进程并输出一些小东西)
  • 没有引发python异常
  • p对象中没有任何内容表明发生了错误

我试过check_call但没有任何成功......

我对自己应该做的事情感到茫然,如果有人能指出我的错误或指示我解决问题,我会感到很高兴......

修改

  • 尝试在Linux上运行此操作(sh)
  • shell是调用的脚本中的变量替换所必需的

编辑2:

根据badp建议,我调整了代码并添加了

subprocess.Popen('ps', shell = True).communicate()

在创建流程的p = ...行之后,这是输出:

/usr/bin/sh /tmp/run/launch.sh
  PID TTY          TIME CMD
29978 pts/0    00:00:01 zsh
 1178 pts/0    00:00:01 python
 1180 pts/0    00:00:00 sh <defunct>
 1181 pts/0    00:00:00 ps
None

显然启动了该过程(即使<defunct>),并且还应该注意到我在传递参数时遇到一些问题...

感谢。

2 个答案:

答案 0 :(得分:4)

我终于找到了问题的答案,感谢badp和他的调试建议。

来自subprocess module上的python页面:

  

可执行文件参数指定要执行的程序。它很少需要:通常,执行的程序由args参数定义。如果shell=True,则可执行文件参数指定要使用的shell。在Unix上,默认shell为/bin/sh。在Windows上,默认shell由COMSPEC环境变量指定。您需要在Windows上指定shell=True的唯一原因是您希望执行的命令实际内置于shell中,例如dircopy。您不需要shell=True来运行批处理文件,也不需要运行基于控制台的可执行文件。

由于我在Linux上使用shell=True,我的命令实际上是由可执行文件执行的参数列表,默认为/bin/sh。因此执行的完整命令是:/bin/sh /usr/bin/sh /tmp/run/launch.sh ...但效果不佳。

我应该使用其中一个:

subprocess.Popen('/tmp/run/launch.sh', shell=True)

subprocess.Popen('/tmp/run/launch.sh', executable = '/usr/bin/sh', shell=True)

shell=True实际上只修改了Linux上的默认可执行文件值,这很棘手......

答案 1 :(得分:3)

试试这个:

p = subprocess.Popen(command,
                     shell = True, #is this even needed?
                     stdin = subprocess.PIPE,
                     stdout = subprocess.PIPE,
                   # stderr = subprocess.STDOUT #uncomment if reqd
                    )

使用ping命令在Windows上进行测试。这样就可以communicate,这可能会帮助您找出脚本未首先启动的原因:)