调试子进程。Popen

2024-04-29 01:31:08 发布

您现在位置:Python中文网/ 问答频道 /正文

我在过去成功地使用了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>),而且还应该注意到,我在传递参数时有一点问题。。。

谢谢。


Tags: 代码脚本nonetrue参数进程shresult
2条回答

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

subprocess module上的python页面:

The executable argument specifies the program to execute. It is very seldom needed: Usually, the program to execute is defined by the args argument. If shell=True, the executable argument specifies which shell to use. On Unix, the default shell is /bin/sh. On Windows, the default shell is specified by the COMSPEC environment variable. The only reason you would need to specify shell=True on Windows is where the command you wish to execute is actually built in to the shell, eg dir, copy. You don’t need shell=True to run a batch file, nor to run a console-based executable.

因为我在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上修改默认的可执行文件值。。。

试试这个:

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,这可能有助于您找出脚本最初没有启动的原因:)

相关问题 更多 >