python中的subprocess

 python2.7 源碼中的註釋(因爲能力有限,翻譯的不太準確):python

這個模塊容許您開啓進程、鏈接輸入、輸出和錯誤的管道,並獲取他們的返回代碼。這個模塊計劃替代一些舊代碼,如:shell

os.system、os.spawn*、os.Popen、popen2.* 、commands.*windows

關於subprocess模塊能夠用來取代這些模塊和功能在下面能夠找到安全

這個模塊定義了一個Popen的類:python2.7

  
  
           
  
  
  1. class Popen(args, bufsize=0, executable=None
  2.             stdin=None, stdout=None, stderr=None
  3.             preexec_fn=None, close_fds=False, shell=False
  4.             cwd=None, env=None, universal_newlines=False
  5.             startupinfo=None, creationflags=0): 

參數爲:ide

args應該是一個字符串或序列的程序命令及參數。程序一般執行序列或字符串的第一項,但能夠經過使用明確的參數進行設置。函數

 

 

在UNIX上,shell = False(默認):在這種狀況下,Popen類使用os.execvp()來執行程序的子進程。args應該一般是一個序列。字符串將被視爲只有一個字符串的序列(程序執行)。spa

在UNIX上,shell= True:若是參數是一個字符串,它指定了經過shell執行命令字符串。若是參數是一個序列,第一項指定命令字符串,其餘的將被視爲附加的shell命令的參數。
 
在Windows:Popen類經過使用CreateProcess()執行這個子進程來對字符串操做。若是參數是一個序列,它將用list2cmdline方法將其轉換成一個字符串。請注意,並非全部的MS Windows應用程序解釋命令行用相同的方法:list2cmdline是專爲應用程序與MS C使用相同的規則。 
 
bufsize,若是給定了,與內置行數open()的參數有相贊成義:0意味着無緩衝的,1意味着線性緩衝,其餘任何正值意味着使用的緩衝區(大約)大小。一個負bufsize意味着使用這個系統默認狀況下,這一般意味着徹底緩衝。默認值爲bufsize是0(無緩衝的)。
 
stdin、stdout和stderr分別指定執行程序的標準輸入,標準輸出和標準錯誤。有效值是PIPE,現有的文件描述符(正整數),現有文件對象,None。PIPE建立一個新的子管道。None,沒有重定向;子管道將會繼承父管道的文件句柄。此外,標準錯誤能夠用STDOUT來定義,代表應用程序應該從STDOUT捕獲到相同的文件句柄的標準錯誤數據。
 
若是preexec_fn設置爲一個可調用對象,該對象將在子進程執行以前調用。
 
若是close_fds 爲True,全部的文件描述符除了0、1和2都會在子進程執行以前關閉。
 
若是shell是True,將經過shell執行指定的命令。
 
若是 cwd 不爲None,子進程將在執行前切換到 cwd指定的目錄
 
若是 env 不爲空,爲新進程定義環境變量
 
若是 universal_newlines 爲 True, 則文件對象標準輸出、標準錯誤輸出以文本文件形式打開, 可是在unix系統中會以\n結束,windows中以\r\n結束。 在python程序中都是看做爲\n 注意: 這種功能僅僅支持用通用換行符構建的python(默認)。同時文件對象標準輸出、標準輸入、標準錯誤的換行符屬性,不會被communicate()模塊所更新。
 
若是給定了startupinfo and creationflags參數, 將會轉交給底層CreateProcess() 函數,他們能夠指定諸如主窗體的外觀、新進程的優先級之類的屬性(僅支持windows)
 
這個模塊也定義了一些簡短的函數:
call(*popenargs, **kwargs):
    運行帶參數的命令.  等待命令完成後返回返回碼屬性。
    這些參數相對於Popen構造函數是相同的。
    Example:
    retcode = call(["ls", "-l"])
 
check_call(*popenargs, **kwargs):
    運行帶參數的命令.  等待命令完成.若是退出碼是0則返回,若是是其餘則拋出      
    CalledProcessError錯誤,該CalledProcessError 對象就會有返回返回碼屬性
    這些參數相對於Popen構造函數是相同的。
    Example:
    check_call(["ls", "-l"])
 
check_output(*popenargs, **kwargs):
    運行帶參數的命令而且以字節字符串來返回。
    若是退出碼是非0則會拋出CalledProcessError。
    CalledProcessError的對象將有返回代碼在returncode屬性和輸出在output屬性
    這些參數相對於Popen構造函數是相同的。
    Example:
    output = check_output(["ls", "-l", "/dev/null"])
 
異常處理:
==============
在新程序開始執行以前子進程拋出異常,以後父進程從新拋出異常。此外,異常對象會有一個額外稱爲'child_traceback'的屬性,從子進程的角度上看,這是一個包含錯誤信息的字符串。 
 
最多見的異常是OSError,好比:執行一個不存在的文件,應用程序會拋出OSError異常
 
若是Popen被無效的參數調用就會拋出‘ValueError’
 
若是check_call() and check_output()在被調用過程當中返回一個非零的返回碼則會拋出‘CalledProcessError’
 
安全
==============
和其餘popen函數不一樣,它不會隱式的執行/bin/sh,這意味着全部的字符,包括shell元字符,能夠安全地傳遞給子進程。
 
Popen 對象
=============
Popen類的實例有如下方法
poll()
    檢查子進程是否終止,返回returncode屬性
 
wait()
    等待子進程終止。返回returncode屬性。
 
communicate(input=None)
    與進程相互做用: 發送數據到標準輸入。從標準輸出、標準錯誤讀取數據, 直到到達文件尾。等待進程終止。可選的input參數應該是發送給子進程的字符串,或者若是沒有要發送給子進程的數據那就用None 
    communicate() 返回一個元組 (stdout, stderr). 
    注意:讀取的數據是保存在緩衝區中,所以,若是數據太大或沒有限制則不要使用這個方法
 
下面的屬性也是有效的:
===================== 
stdin
    若是stdin參數是PIPE,這個屬性是提供輸入到子進程一個文件對象,不然爲None
 
stdout
    若是stdout參數是PIPE , 這個屬性是提供輸出到子進程一個文件對象,不然爲None
 
stderr
     若是stderr參數是PIPE , 這個屬性是提供錯誤輸出到子進程一個文件對象,不然爲None
 
pid
    子進程的PID
 
returncode
    子進程的返回碼。空值表示進程尚未結束,一個負值‘-N’表示子進程被信號N所結束(僅unix支持)
 
用subprocess模塊取代舊函數:
====================================================
在本節中, "a ==> b" 意味着 b 能夠替代 a.
 
注意: 若是沒有找到執行程序,全部在本節中的函數都有可能以靜默狀態失敗;這個模塊會拋出OSError異常
 
在如下的例子中, 咱們假設subprocess 模塊是"from subprocess import *" 這樣導入的:
 
 
         
         
                  
         
         
  1. 替代 /bin/sh shell 的引號部分 
  2. --------------------------------- 
  3. output=`mycmd myarg` 
  4. ==> 
  5. output = Popen(["mycmd""myarg"], stdout=PIPE).communicate()[0
  6.  
  7.  
  8. 替代 shell 的管道
  9. ------------------------- 
  10. output=`dmesg | grep hda` 
  11. ==> 
  12. p1 = Popen(["dmesg"], stdout=PIPE) 
  13. p2 = Popen(["grep""hda"], stdin=p1.stdout, stdout=PIPE) 
  14. output = p2.communicate()[0
  15.  
  16.  
  17. 替代 os.system() 
  18. --------------------- 
  19. sts = os.system("mycmd" + " myarg"
  20. ==> 
  21. p = Popen("mycmd" + " myarg", shell=True
  22. pid, sts = os.waitpid(p.pid, 0
  23.  
  24. 注意: 
  25.  
  26. * 經過shell調用程序一般不是必須的 
  27.  
  28. * 查看returncode attribute要比exitstatus容易些. 
  29.  
  30. 一個更現實的例子: 
  31.  
  32. try
  33.     retcode = call("mycmd" + " myarg", shell=True
  34.     if retcode < 0
  35.         print >>sys.stderr, "Child was terminated by signal", -retcode 
  36.     else
  37.         print >>sys.stderr, "Child returned", retcode 
  38. except OSError, e: 
  39.     print >>sys.stderr, "Execution failed:", e 
  40.  
  41.  
  42. 替代 os.spawn* 
  43. ------------------- 
  44. P_NOWAIT example: 
  45.  
  46. pid = os.spawnlp(os.P_NOWAIT, "/bin/mycmd""mycmd""myarg"
  47. ==> 
  48. pid = Popen(["/bin/mycmd""myarg"]).pid 
  49.  
  50.  
  51. P_WAIT example: 
  52.  
  53. retcode = os.spawnlp(os.P_WAIT, "/bin/mycmd""mycmd""myarg"
  54. ==> 
  55. retcode = call(["/bin/mycmd""myarg"]) 
  56.  
  57.  
  58. Vector example: 
  59.  
  60. os.spawnvp(os.P_NOWAIT, path, args) 
  61. ==> 
  62. Popen([path] + args[1:]) 
  63.  
  64.  
  65. Environment example: 
  66.  
  67. os.spawnlpe(os.P_NOWAIT, "/bin/mycmd""mycmd""myarg", env) 
  68. ==> 
  69. Popen(["/bin/mycmd""myarg"], env={"PATH""/usr/bin"}) 
  70.  
  71.  
  72. 替代 os.popen* 
  73. ------------------- 
  74. pipe = os.popen("cmd", mode='r', bufsize) 
  75. ==> 
  76. pipe = Popen("cmd", shell=True, bufsize=bufsize, stdout=PIPE).stdout 
  77.  
  78. pipe = os.popen("cmd", mode='w', bufsize) 
  79. ==> 
  80. pipe = Popen("cmd", shell=True, bufsize=bufsize, stdin=PIPE).stdin 
  81.  
  82.  
  83. (child_stdin, child_stdout) = os.popen2("cmd", mode, bufsize) 
  84. ==> 
  85. p = Popen("cmd", shell=True, bufsize=bufsize, 
  86.           stdin=PIPE, stdout=PIPE, close_fds=True
  87. (child_stdin, child_stdout) = (p.stdin, p.stdout) 
  88.  
  89.  
  90. (child_stdin, 
  91.  child_stdout, 
  92.  child_stderr) = os.popen3("cmd", mode, bufsize) 
  93. ==> 
  94. p = Popen("cmd", shell=True, bufsize=bufsize, 
  95.           stdin=PIPE, stdout=PIPE, stderr=PIPE, close_fds=True
  96. (child_stdin, 
  97.  child_stdout, 
  98.  child_stderr) = (p.stdin, p.stdout, p.stderr) 
  99.  
  100.  
  101. (child_stdin, child_stdout_and_stderr) = os.popen4("cmd", mode, 
  102.                                                    bufsize) 
  103. ==> 
  104. p = Popen("cmd", shell=True, bufsize=bufsize, 
  105.           stdin=PIPE, stdout=PIPE, stderr=STDOUT, close_fds=True
  106. (child_stdin, child_stdout_and_stderr) = (p.stdin, p.stdout) 
  107.  
  108. 在 Unix系統中, os.popen2, os.popen3  os.popen4 一樣能夠在沒有shell介入的狀況下直接傳遞給程序
  109. 以序列形式執行命令行  
  110. 這種方法能夠用下面的方法替換
  111.  
  112. (child_stdin, child_stdout) = os.popen2(["/bin/ls""-l"], mode, 
  113.                                         bufsize) 
  114. ==> 
  115. p = Popen(["/bin/ls""-l"], bufsize=bufsize, stdin=PIPE, stdout=PIPE) 
  116. (child_stdin, child_stdout) = (p.stdin, p.stdout) 
  117.  
  118. Return code handling translates as follows: 
  119.  
  120. pipe = os.popen("cmd"'w'
  121. ... 
  122. rc = pipe.close() 
  123. if rc is not None and rc % 256
  124.     print "There were some errors" 
  125. ==> 
  126. process = Popen("cmd"'w', shell=True, stdin=PIPE) 
  127. ... 
  128. process.stdin.close() 
  129. if process.wait() != 0
  130.     print "There were some errors" 
  131.  
  132.  
  133. 替代 popen2.* 
  134. ------------------ 
  135. (child_stdout, child_stdin) = popen2.popen2("somestring", bufsize, mode) 
  136. ==> 
  137. p = Popen(["somestring"], shell=True, bufsize=bufsize 
  138.           stdin=PIPE, stdout=PIPE, close_fds=True
  139. (child_stdout, child_stdin) = (p.stdout, p.stdin) 
  140.  
  141. 在 Unix系統中, popen2 也能夠在沒有shell介入的狀況下直接傳遞給程序以序列形式執行命令行.  
  142. 這種方法能夠用下面的方法替換: 
  143.  
  144. (child_stdout, child_stdin) = popen2.popen2(["mycmd""myarg"], bufsize, 
  145.                                             mode) 
  146. ==> 
  147. p = Popen(["mycmd""myarg"], bufsize=bufsize, 
  148.           stdin=PIPE, stdout=PIPE, close_fds=True
  149. (child_stdout, child_stdin) = (p.stdout, p.stdin) 
  150.  
  151. The popen2.Popen3 and popen2.Popen4 basically works as subprocess.Popen, 
  152. except that: 
  153.  
  154. * subprocess.Popen raises an exception if the execution fails 
  155. * the capturestderr argument is replaced with the stderr argument. 
  156. * stdin=PIPE and stdout=PIPE must be specified. 
  157. * popen2 closes all filedescriptors by default, but you have to specify 
  158.   close_fds=True with subprocess.Popen. 
相關文章
相關標籤/搜索