我正在使用cwiid庫,這是一個用C語言編寫的庫,但在python中使用。該庫允許我使用Wiimote來控制機器人上的一些電機。該代碼在沒有監視器,鍵盤或鼠標的嵌入式設備上作爲守護進程運行。如果我不使用子進程,如何用python讀stderr?
當我嘗試初始化對象:時間
import cwiid
while True:
try:
wm = cwiid.Wiimote()
except RuntimeError:
# RuntimeError exception thrown if no Wiimote is trying to connect
# Wait a second
time.sleep(1)
# Try again
continue
99%,一切正常,但過一段時間,圖書館進入某種奇怪的狀態,其中調用cwiid.Wiimote()
結果庫編寫「套接字連接錯誤(控制通道)」到stderr,並且python拋出異常。發生這種情況時,每次後續調用cwiid.Wiimote()
都會導致同樣的事情被寫入stderr,並且在重新啓動設備之前拋出相同的異常。
我想要做的是檢測到這個問題,並讓python自動重啓設備。
cwiid庫在怪異狀態下拋出異常的類型也是RuntimeError
,這與連接超時異常(這很常見)沒有什麼不同,所以我似乎無法區分它。我想要做的就是在運行cwiid.Wiimote()
之後立即閱讀stderr,看看是否顯示消息「套接字連接錯誤(控制通道)」出現,如果有,請重新啓動。
到目前爲止,我可以重定向stderr以防止消息通過使用某些os.dup()
和os.dup2()
方法顯示出來,但這看起來不會幫助我閱讀stderr。
如果您正在使用子進程運行某些內容(在此情況下不適用),則大多數在線示例處理讀取stderr。
我該如何去閱讀stderr來檢測正在寫入的消息?
我想我正在尋找的是這樣的:
while True:
try:
r, w = os.pipe()
os.dup2(sys.stderr.fileno(), r)
wm = cwiid.Wiimote()
except RuntimeError:
# RuntimeError exception thrown if no Wiimote is trying to connect
if ('Socket connect error (control channel)' in os.read(r, 100)):
# Reboot
# Wait a second
time.sleep(1)
# Try again
continue
這似乎並沒有工作,我認爲它應該不過的方式。
經常有一個錯誤消息,但有一個例外。你可以把'RuntimeError as e:'除外,然後用'str(e)'讀取錯誤信息,並根據消息做出不同的反應。 – SethMMorton
看過github上的庫代碼後,你可能會不走運。就像現在一樣,特定的連接錯誤(如您所報告的錯誤)只會打印到'stderr',然後集中在一起,出現錯誤信息字符串爲「」,打開連接「錯誤」的RuntimeError。什麼SethMMorton說是有效的,但你可能不會找到那裏的stderr字符串。至少還沒有。 根據原始問題,攔截另一個進程的'stderr',這可能太多了,但值得檢查:http://github.com/jerome-pouiller/reredirect 祝你好運。 – sal
好吧,我可以告訴你如何按照你想要的方式在進程內重定向stderr,但是你能否在你的循環示例中闡明一些東西:你甚至用'wm'做了什麼?看起來,如果對cwiid.Wiimote()的調用成功,您只需立即重新循環 - 「True」中沒有「break」。 –