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
。