python 调试 subprocess.Popen 调用
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2206407/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Debugging a subprocess.Popen call
提问by Matthieu M.
I have been using subprocess.Popensuccessfully in the past, when wrapping binaries with a python script to format arguments / customize etc...
我过去一直在subprocess.Popen成功使用,当用 python 脚本包装二进制文件以格式化参数/自定义等时......
Developing a nth wrapper, I did as usual... but nothing happens.
开发第 n 个包装器,我像往常一样......但没有任何反应。
Here is the little code:
这是小代码:
print command
p = subprocess.Popen(command, shell = True)
result = p.communicate()[0]
print vars(p)
return result
And here is the output:
这是输出:
/usr/bin/sh /tmp/run/launch.sh
{'_child_created': True, 'returncode': 0, 'stdout': None, 'stdin': None, 'pid': 21650, 'stderr': None, 'universal_newlines': False}
As you can see, the goal is to create a shell script setting up everything I need, and then executing it. I would prefer to use real python code, but unfortunately launch.shcall 3rd party shell scripts that I have no wish to try and replicate (though I've been insisting for a python api for over a year now).
如您所见,目标是创建一个 shell 脚本来设置我需要的一切,然后执行它。我更喜欢使用真正的 python 代码,但不幸的是launch.sh调用了我不想尝试和复制的 3rd 方 shell 脚本(尽管我已经坚持使用 python api 一年多了)。
The problem is that:
问题在于:
- the shell script is not executed (it should spawn process and output some little things)
- no python exception is raised
- there is nothing in the
pobject that indicates that an error occurred
- 不执行 shell 脚本(它应该产生进程并输出一些小东西)
- 没有引发python异常
p对象中没有任何内容表明发生了错误
I have tried check_callwithout any success either...
我也试过check_call没有成功...
I am at a loss regarding what I should do, and would be very glad if someone could either point my mistake or direct me toward resolution...
我不知道我应该做什么,如果有人能指出我的错误或指导我解决问题,我会很高兴......
EDIT:
编辑:
- Trying to run this on Linux (sh)
- shell is necessary for variable substitution in the scripts invoked
- 尝试在 Linux (sh) 上运行它
- shell 对于调用的脚本中的变量替换是必需的
EDIT 2:
编辑2:
Following badpsuggestion, I tweaked the code and added
根据badp建议,我调整了代码并添加了
subprocess.Popen('ps', shell = True).communicate()
Right after p = ...line that creates the process, here is the output:
在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
Apparently the process is launched (even though <defunct>) and one should also note that I have a little problem passing the parameters in...
显然该进程已启动(即使<defunct>),并且还应该注意我在传递参数时遇到了一些问题......
Thanks.
谢谢。
采纳答案by Matthieu M.
I've finally found the answer to my question, thanks to badpand his suggestions for debugging.
我终于找到了我的问题的答案,感谢badp和他的调试建议。
From the python page on the subprocess module:
从subprocess 模块上的 python 页面:
The executableargument 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 executableargument specifies which shell to use. On Unix, the default shell is/bin/sh. On Windows, the default shell is specified by theCOMSPECenvironment variable. The only reason you would need to specifyshell=Trueon Windows is where the command you wish to execute is actually built in to the shell, egdir,copy. You don't needshell=Trueto run a batch file, nor to run a console-based executable.
该可执行文件参数指定要执行的程序。很少需要它:通常,要执行的程序由 args 参数定义。如果
shell=True,则可执行参数指定要使用的 shell。在 Unix 上,默认的 shell 是/bin/sh. 在 Windows 上,默认 shell 由COMSPEC环境变量指定。您需要shell=True在 Windows上指定的唯一原因是您希望执行的命令实际上内置到 shell 中的位置,例如dir,copy. 您不需要shell=True运行批处理文件,也不需要运行基于控制台的可执行文件。
Since I am on Linux and using shell=True, my command is in fact a list of arguments to be executed by executable, which defaults to /bin/sh. Thus the full command executed was: /bin/sh /usr/bin/sh /tmp/run/launch.sh... which did not work so well.
由于我在 Linux 上使用shell=True,我的命令实际上是由可执行文件执行的参数列表,默认为/bin/sh. 因此,执行的完整命令是:/bin/sh /usr/bin/sh /tmp/run/launch.sh... 效果不佳。
And I should have used either:
我应该使用:
subprocess.Popen('/tmp/run/launch.sh', shell=True)
or
或者
subprocess.Popen('/tmp/run/launch.sh', executable = '/usr/bin/sh', shell=True)
It's tricky that shell=Truewould actually modify the default executablevalue on Linux only...
shell=True实际上只在 Linux 上修改默认的可执行值是很棘手的......
回答by badp
Try this:
试试这个:
p = subprocess.Popen(command,
shell = True, #is this even needed?
stdin = subprocess.PIPE,
stdout = subprocess.PIPE,
# stderr = subprocess.STDOUT #uncomment if reqd
)
Tested working on Windows with the pingcommand. This lets you communicate, which might help you find out why the script isn't launched in the first place :)
使用ping命令在 Windows 上进行了测试。这可以让您communicate,这可能会帮助您找出脚本没有首先启动的原因:)

