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.Popen
successfully 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.sh
call 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
p
object that indicates that an error occurred
- 不执行 shell 脚本(它应该产生进程并输出一些小东西)
- 没有引发python异常
p
对象中没有任何内容表明发生了错误
I have tried check_call
without 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 badp
suggestion, 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 badp
and 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 theCOMSPEC
environment variable. The only reason you would need to specifyshell=True
on Windows is where the command you wish to execute is actually built in to the shell, egdir
,copy
. You don't needshell=True
to 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=True
would 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 ping
command. This lets you communicate
, which might help you find out why the script isn't launched in the first place :)
使用ping
命令在 Windows 上进行了测试。这可以让您communicate
,这可能会帮助您找出脚本没有首先启动的原因:)