Popen 具有更大的靈活性
與 subprocess.call 相比,使用 subprocess.Popen 可以對啟動的程序進行更細粒度的控制。
啟動子流程
process = subprocess.Popen([r'C:\path\to\app.exe', 'arg1', '--flag', 'arg'])
Popen 的簽名與 call 函式非常相似; 但是,Popen 將立即返回,而不是像 call 那樣等待子程序完成。
等待子程序完成
process = subprocess.Popen([r'C:\path\to\app.exe', 'arg1', '--flag', 'arg'])
process.wait()
從子程序讀取輸出
process = subprocess.Popen([r'C:\path\to\app.exe'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
# This will block until process completes
stdout, stderr = process.communicate()
print stdout
print stderr
對正在執行的子程序的互動式訪問
即使子程序尚未完成,你也可以在 stdin 和 stdout 上進行讀寫。當在另一個程式中自動執行功能時,這可能很有用。
寫入子程序
process = subprocess.Popen([r'C:\path\to\app.exe'], stdout = subprocess.PIPE, stdin = subprocess.PIPE)
process.stdin.write('line of input\n') # Write input
line = process.stdout.readline() # Read a line from stdout
# Do logic on line read.
但是,如果你只需要一組輸入和輸出,而不是動態互動,則應使用 communicate() 而不是直接訪問 stdin 和 stdout。
從子程序讀取流
如果你想逐行檢視子流程的輸出,可以使用以下程式碼段:
process = subprocess.Popen(<your_command>, stdout=subprocess.PIPE)
while process.poll() is None:
output_line = process.stdout.readline()
如果子命令輸出沒有 EOL 字元,則上述程式碼段不起作用。然後,你可以按字元讀取輸出字元,如下所示:
process = subprocess.Popen(<your_command>, stdout=subprocess.PIPE)
while process.poll() is None:
output_line = process.stdout.read(1)
指定為 read 方法的引數的 1 告訴 read 在時間讀取 1 個字元。你可以指定使用不同的數字讀取所需的字元數。負數或 0 告訴 read 讀取單個字串,直到遇到 EOF( 參見此處 )。
在上面的兩個片段中,process.poll() 都是 None,直到子程序完成。一旦沒有更多輸出要讀取,這用於退出迴圈。
相同的過程可以應用於子過程的 stderr。