subprocess也是一個(gè)常用的模塊补胚,目前工作所涉及的都比較淺蒂教,所以這里只列出一些基本用法和注意點(diǎn)(只適用*nix系統(tǒng))。以后用到advanced的內(nèi)容畴嘶,會(huì)更新此文章蛋逾。refer to: python DOC
定義:
spawn新的進(jìn)程,連接input/output/error管道窗悯,并獲取錯(cuò)誤碼区匣。
以下模塊不建議繼續(xù)使用,而用subprocess取代:
os.system
os.spawn*
os.popen*
popen2.*
commands.*
subprocess確實(shí)是更加強(qiáng)大蒋院,而且以前的模塊有時(shí)候會(huì)有bug亏钩。
用法:
-
call:
import subprocess
subprocess.call(["ls", "-l"])
subprocess.call("exit 1", shell=True)
如果只需要獲取子進(jìn)程的錯(cuò)誤碼,這個(gè)方法就足夠了欺旧,而且非常好用姑丑。
可以看到它有兩種用法,doc里推薦第一種辞友,就是傳一個(gè)字符串list(把cmd split成為一個(gè)list)栅哀。第二種呢是直接傳一個(gè)字符串cmd,并把參數(shù)shell賦值為true称龙。
如果用第一種的話留拾,有個(gè)模塊shlex,可以把cmd分解成list茵瀑,并很好的處理空格和引號(hào)间驮。cmd復(fù)雜的話建議這么使用,不會(huì)出錯(cuò)马昨。
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'"]
第二種用法簡(jiǎn)單易懂竞帽,就不說(shuō)了扛施。看似兩種方法都可以屹篓,但這里有個(gè)很大的坑:
如果cmd里有管道符疙渣,一定要用第二種,否則exit code會(huì)不準(zhǔn)堆巧。
具體原因我還沒(méi)細(xì)看妄荔,童鞋們有精力可以深入研究一下。就是因?yàn)檫@個(gè)坑才讓我重新學(xué)習(xí)這個(gè)模塊谍肤,也就有了這篇blog...
-
check_call和check_output:
check_call和call用法基本一樣啦租,唯一的不同點(diǎn)是如果exit code非零,check_call會(huì)raise一個(gè)CalledProcessError荒揣。
check_output也是一樣的道理篷角,非零會(huì)raise一個(gè)CalledProcessError。但它return的是output系任。它還有個(gè)屬性returncode來(lái)獲取退出碼恳蹲。
-
Popen:
最common的方法,可以操作input/output/error管道俩滥,并獲得exit code嘉蕾。
Popen和前面的方法有個(gè)很大的不同點(diǎn)是, process會(huì)丟在后臺(tái)運(yùn)行。 而call等方法會(huì)等到proccess運(yùn)行結(jié)束才返回霜旧。在使用的時(shí)候要多加注意错忱。
我用一段代碼來(lái)說(shuō)明其用法:
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)
應(yīng)該很容易看懂吧。
That's it.