我正在尝试使用python来帮助围绕Android构建系统中的增量构建功能执行一些自动化操作。通常,在给定的目录中,我会执行以下命令来构建该目录和子目录中的任何内容:
mm -j8
这类似于"make“命令,只是它是增量构建,并在名为envsetup.sh的bash文件中定义为函数。它是什么并不重要,只要知道它是在文件系统中某个bash脚本中定义的函数。要执行此操作,我还可以执行以下操作:
bash -c ". /path/to/envsetup.sh; mm -j8"
这种调用它的方法在从python调用函数时非常重要。我遵循了解决方案here,它展示了如何从python中调用bash脚本中的函数。我已经在一个简单的脚本中使用了这个方法,从理论上讲,它应该只是从执行命令中输出STDOUT和STDERR:
import subprocess
command = ['bash', '-c', '. /path/to/envsetup.sh; mm -j8']
(stdout, stderr) = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True).communicate()
print 'stdout: ' + stdout
print 'stderr: ' + stderr
但是,对Popen
的调用永远不会返回。我做错了什么,允许bash正确执行命令,但Python在执行命令时挂起?
发布于 2012-03-21 22:04:55
tl;dr:
您的问题是shell=True
的使用。将它设置为shell=False
,它就会起作用。
设置此选项后,python将只运行command
数组的第一个元素,即bash
作为外壳脚本。因此,目前python正在启动自己的外壳程序,以便运行您的命令(bash
)。它将不带参数地运行bash,然后bash将等待输入,从而阻塞您的python脚本。
shell=True
设置用于将shell脚本作为单个字符串传递的用例。当您显式地将shell及其参数指定为要调用的进程时,应该设置shell=False
。
>>> import subprocess
>>> subprocess.Popen(['bash', 'whatever'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True).communicate()
下面是我运行上述命令时进程树外观:
\_ python
\_ /bin/sh -c bash whatever
\_ bash
whatever
实际上是传入的,但它是sh
的参数,而不是内部bash
的参数,所以运行的命令实际上是['/bin/sh', '-c', 'bash', 'whatever']
,这与['/bin/sh', '-c', 'bash whatever']
非常不同
https://stackoverflow.com/questions/9813003
复制相似问题