python2.7 源碼中的註釋(因爲能力有限,翻譯的不太準確):python
這個模塊容許您開啓進程、鏈接輸入、輸出和錯誤的管道,並獲取他們的返回代碼。這個模塊計劃替代一些舊代碼,如:shell
os.system、os.spawn*、os.Popen、popen2.* 、commands.*windows
關於subprocess模塊能夠用來取代這些模塊和功能在下面能夠找到安全
這個模塊定義了一個Popen的類:python2.7
- class Popen(args, bufsize=0, executable=None,
- stdin=None, stdout=None, stderr=None,
- preexec_fn=None, close_fds=False, shell=False,
- cwd=None, env=None, universal_newlines=False,
- startupinfo=None, creationflags=0):
參數爲:ide
args應該是一個字符串或序列的程序命令及參數。程序一般執行序列或字符串的第一項,但能夠經過使用明確的參數進行設置。函數
在UNIX上,shell = False(默認):在這種狀況下,Popen類使用os.execvp()來執行程序的子進程。args應該一般是一個序列。字符串將被視爲只有一個字符串的序列(程序執行)。spa
- 替代 /bin/sh shell 的引號部分
- ---------------------------------
- output=`mycmd myarg`
- ==>
- output = Popen(["mycmd", "myarg"], stdout=PIPE).communicate()[0]
- 替代 shell 的管道
- -------------------------
- output=`dmesg | grep hda`
- ==>
- p1 = Popen(["dmesg"], stdout=PIPE)
- p2 = Popen(["grep", "hda"], stdin=p1.stdout, stdout=PIPE)
- output = p2.communicate()[0]
- 替代 os.system()
- ---------------------
- sts = os.system("mycmd" + " myarg")
- ==>
- p = Popen("mycmd" + " myarg", shell=True)
- pid, sts = os.waitpid(p.pid, 0)
- 注意:
- * 經過shell調用程序一般不是必須的
- * 查看returncode attribute要比exitstatus容易些.
- 一個更現實的例子:
- try:
- retcode = call("mycmd" + " myarg", shell=True)
- if retcode < 0:
- print >>sys.stderr, "Child was terminated by signal", -retcode
- else:
- print >>sys.stderr, "Child returned", retcode
- except OSError, e:
- print >>sys.stderr, "Execution failed:", e
- 替代 os.spawn*
- -------------------
- P_NOWAIT example:
- pid = os.spawnlp(os.P_NOWAIT, "/bin/mycmd", "mycmd", "myarg")
- ==>
- pid = Popen(["/bin/mycmd", "myarg"]).pid
- P_WAIT example:
- retcode = os.spawnlp(os.P_WAIT, "/bin/mycmd", "mycmd", "myarg")
- ==>
- retcode = call(["/bin/mycmd", "myarg"])
- Vector example:
- os.spawnvp(os.P_NOWAIT, path, args)
- ==>
- Popen([path] + args[1:])
- Environment example:
- os.spawnlpe(os.P_NOWAIT, "/bin/mycmd", "mycmd", "myarg", env)
- ==>
- Popen(["/bin/mycmd", "myarg"], env={"PATH": "/usr/bin"})
- 替代 os.popen*
- -------------------
- pipe = os.popen("cmd", mode='r', bufsize)
- ==>
- pipe = Popen("cmd", shell=True, bufsize=bufsize, stdout=PIPE).stdout
- pipe = os.popen("cmd", mode='w', bufsize)
- ==>
- pipe = Popen("cmd", shell=True, bufsize=bufsize, stdin=PIPE).stdin
- (child_stdin, child_stdout) = os.popen2("cmd", mode, bufsize)
- ==>
- p = Popen("cmd", shell=True, bufsize=bufsize,
- stdin=PIPE, stdout=PIPE, close_fds=True)
- (child_stdin, child_stdout) = (p.stdin, p.stdout)
- (child_stdin,
- child_stdout,
- child_stderr) = os.popen3("cmd", mode, bufsize)
- ==>
- p = Popen("cmd", shell=True, bufsize=bufsize,
- stdin=PIPE, stdout=PIPE, stderr=PIPE, close_fds=True)
- (child_stdin,
- child_stdout,
- child_stderr) = (p.stdin, p.stdout, p.stderr)
- (child_stdin, child_stdout_and_stderr) = os.popen4("cmd", mode,
- bufsize)
- ==>
- p = Popen("cmd", shell=True, bufsize=bufsize,
- stdin=PIPE, stdout=PIPE, stderr=STDOUT, close_fds=True)
- (child_stdin, child_stdout_and_stderr) = (p.stdin, p.stdout)
- 在 Unix系統中, os.popen2, os.popen3 與 os.popen4 一樣能夠在沒有shell介入的狀況下直接傳遞給程序
- 以序列形式執行命令行
- 這種方法能夠用下面的方法替換:
- (child_stdin, child_stdout) = os.popen2(["/bin/ls", "-l"], mode,
- bufsize)
- ==>
- p = Popen(["/bin/ls", "-l"], bufsize=bufsize, stdin=PIPE, stdout=PIPE)
- (child_stdin, child_stdout) = (p.stdin, p.stdout)
- Return code handling translates as follows:
- pipe = os.popen("cmd", 'w')
- ...
- rc = pipe.close()
- if rc is not None and rc % 256:
- print "There were some errors"
- ==>
- process = Popen("cmd", 'w', shell=True, stdin=PIPE)
- ...
- process.stdin.close()
- if process.wait() != 0:
- print "There were some errors"
- 替代 popen2.*
- ------------------
- (child_stdout, child_stdin) = popen2.popen2("somestring", bufsize, mode)
- ==>
- p = Popen(["somestring"], shell=True, bufsize=bufsize
- stdin=PIPE, stdout=PIPE, close_fds=True)
- (child_stdout, child_stdin) = (p.stdout, p.stdin)
- 在 Unix系統中, popen2 也能夠在沒有shell介入的狀況下直接傳遞給程序以序列形式執行命令行.
- 這種方法能夠用下面的方法替換:
- (child_stdout, child_stdin) = popen2.popen2(["mycmd", "myarg"], bufsize,
- mode)
- ==>
- p = Popen(["mycmd", "myarg"], bufsize=bufsize,
- stdin=PIPE, stdout=PIPE, close_fds=True)
- (child_stdout, child_stdin) = (p.stdout, p.stdin)
- The popen2.Popen3 and popen2.Popen4 basically works as subprocess.Popen,
- except that:
- * subprocess.Popen raises an exception if the execution fails
- * the capturestderr argument is replaced with the stderr argument.
- * stdin=PIPE and stdout=PIPE must be specified.
- * popen2 closes all filedescriptors by default, but you have to specify
- close_fds=True with subprocess.Popen.