调试subprocess.Popen调用

Mat*_* M. 8 python subprocess

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

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

这是小代码:

print command
p = subprocess.Popen(command, shell = True)
result = p.communicate()[0]
print vars(p)
return result
Run Code Online (Sandbox Code Playgroud)

这是输出:

/usr/bin/sh /tmp/run/launch.sh
{'_child_created': True, 'returncode': 0, 'stdout': None, 'stdin': None, 'pid': 21650, 'stderr': None, 'universal_newlines': False}
Run Code Online (Sandbox Code Playgroud)

如您所见,目标是创建一个shell脚本来设置我需要的所有内容,然后执行它.我更愿意用实际的Python代码,但不幸的是launch.sh叫我没有想尝试和复制(虽然我一直在坚持了一个Python API超过一年)的第三方shell脚本.

问题是:

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

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

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

编辑:

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

编辑2:

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

subprocess.Popen('ps', shell = True).communicate()
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

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

谢谢.

bad*_*adp 6

尝试这个:

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

使用命令在 Windows 上测试工作ping。这可以让您communicate,这可能会帮助您找出为什么脚本没有首先启动:)


Mat*_* M. 5

我终于找到了问题的答案,这要归功于badp他的调试建议。

子流程模块的python页面上:

可执行文件参数指定要执行的程序。很少需要:通常,要执行的程序由args参数定义。如果为shell=True则可执行参数指定要使用的外壳。在Unix上,默认外壳为/bin/sh。在Windows上,默认外壳由COMSPEC环境变量指定。你需要指定的唯一原因,shell=True在Windows上是要在其中执行命令实际上是内置在外壳,例如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)
Run Code Online (Sandbox Code Playgroud)

要么

subprocess.Popen('/tmp/run/launch.sh', executable = '/usr/bin/sh', shell=True)
Run Code Online (Sandbox Code Playgroud)

shell=True实际上仅在Linux上修改默认可执行文件值是棘手的...