[英]subprocess stderr vs sys.stderr
我不確定這個問題是Python還是shell問題。
我有一個Python程序,它對命令使用子進程調用,該命令可以在stderr上發出錯誤消息。 我自己的程序也使用sys.stderr來記錄錯誤。 這是一個簡單的例子,命令(ls * .foobar)失敗:
import sys,subprocess
sys.stderr.write("--Hello\n")
try:
subprocess.check_call("ls *.foobar",shell=True)
except subprocess.CalledProcessError as e:
sys.stderr.write("Command failed\n")
sys.stderr.write("--Bye\n")
當我運行此代碼時,控制台上的ouptut(來自stderr)如下:
- 你好
ls:無法訪問'* .foobar':沒有這樣的文件或目錄
命令失敗
--Bye
如果我將stderr重定向到文件(例如使用python myscript.py 2> log),該文件包含以下內容:
ls:無法訪問'* .foobar':沒有這樣的文件或目錄
- 你好
命令失敗
--Bye
有沒有辦法保持文件中的消息順序(除了在子進程調用中使用stderr在文件上的顯式重定向)?
這個問題類似於一些標准的stdout / stderr問題,但是,在這里,一切都應該在stderr上。
您需要將數據寫入器刷新到stderr
描述符:
sys.stderr.write("--Hello\n")
sys.stderr.flush()
當連接到終端時,stdio是行緩沖的,當連接到管道時使用固定緩沖區。 您正在編寫一個\\n
換行符,當連接到終端時觸發刷新,但是,如果沒有每行刷新,則在Python退出時,在寫入最終刷新之前,不會寫入足以讓stderr
觸發緩沖區刷新。
如果你使用print(..., file=sys.stderr)
你可以通過添加flush=True
告訴print()
發出flush()
調用:
print("--Hello", file=sys.stderr, flush=True)
處理此問題的另一種方法是“捕獲並釋放”子進程的stderr輸出:
sys.stderr.write("--Hello\n")
try:
subprocess.check_call("ls *.foobar", shell=True, stderr=subprocess.PIPE)
except subprocess.CalledProcessError as e:
sys.stderr.write(e.stderr)
sys.stderr.write("Command failed\n")
sys.stderr.write("--Bye\n")
stderr=subprocess.PIPE
添加告訴subprocess
e.stderr
捕獲命令的stderr輸出,並且您可以將該輸出作為CalledProcessError
異常的e.stderr
屬性找到。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.