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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-04 00:04:14  来源:igfitidea点击:

Debugging a subprocess.Popen call

pythonsubprocess

提问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 the COMSPECenvironment variable. The only reason you would need to specify shell=Trueon Windows is where the command you wish to execute is actually built in to the shell, eg dir, copy. You don't need shell=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,这可能会帮助您找出脚本没有首先启动的原因:)