subprocess也是一个常用的模块,目前工作所涉及的都比较浅,所以这里只列出一些基本用法和注意点(只适用*nix系统)。以后用到advanced的内容,会更新此文章。refer to: python DOC
定义:
spawn新的进程,连接input/output/error管道,并获取错误码。
以下模块不建议继续使用,而用subprocess取代:
os.system
os.spawn*
os.popen*
popen2.*
commands.*
subprocess确实是更加强大,而且以前的模块有时候会有bug。
用法:
-
call:
import subprocess
subprocess.call(["ls", "-l"])
subprocess.call("exit 1", shell=True)
如果只需要获取子进程的错误码,这个方法就足够了,而且非常好用。
可以看到它有两种用法,doc里推荐第一种,就是传一个字符串list(把cmd split成为一个list)。第二种呢是直接传一个字符串cmd,并把参数shell赋值为true。
如果用第一种的话,有个模块shlex,可以把cmd分解成list,并很好的处理空格和引号。cmd复杂的话建议这么使用,不会出错。
import shlex
command_line = raw_input()
/bin/vikings -input eggs.txt -output "spam spam.txt" -cmd "echo '$MONEY'"
args = shlex.split(command_line)
print args
['/bin/vikings', '-input', 'eggs.txt', '-output', 'spam spam.txt', '-cmd', "echo '$MONEY'"]
第二种用法简单易懂,就不说了。看似两种方法都可以,但这里有个很大的坑:
如果cmd里有管道符,一定要用第二种,否则exit code会不准。
具体原因我还没细看,童鞋们有精力可以深入研究一下。就是因为这个坑才让我重新学习这个模块,也就有了这篇blog...
-
check_call和check_output:
check_call和call用法基本一样,唯一的不同点是如果exit code非零,check_call会raise一个CalledProcessError。
check_output也是一样的道理,非零会raise一个CalledProcessError。但它return的是output。它还有个属性returncode来获取退出码。
-
Popen:
最common的方法,可以操作input/output/error管道,并获得exit code。
Popen和前面的方法有个很大的不同点是, process会丢在后台运行。 而call等方法会等到proccess运行结束才返回。在使用的时候要多加注意。
我用一段代码来说明其用法:
import shlex
from subprocess import Popen, PIPE
def get_exitcode_stdout_stderr(cmd):
"""
Execute the external command and get its exitcode, stdout and stderr.
"""
args = shlex.split(cmd)
proc = Popen(args, stdout=PIPE, stderr=PIPE)
out, err = proc.communicate()
exitcode = proc.returncode
return exitcode, out, err
cmd = "..." # arbitrary external command, e.g. "python mytest.py"
exitcode, out, err = get_exitcode_stdout_stderr(cmd)
应该很容易看懂吧。
That's it.