2013-04-22 68 views
1

我已經搜索了很長時間瞭解這個問題的答案,我想很多方面都與我對子進程模塊的工作方式不熟悉有關。如果有人感興趣,這是一個模糊的程序。另外,我要指出,這是所有被Linux中做(我認爲這是相關的)我有一些像這樣的代碼:sqlite的子進程,編碼和日誌記錄的問題

# open and run a process and log get return code and stderr information 
process = subprocess.Popen([app, file_name], stdout=subprocess.PIPE, 
              stderr=subprocess.PIPE) 
return_code = process.wait() 
err_msg = process.communicate()[1] 

# insert results into an sqlite database log 
log_cur.execute('''INSERT INTO log (return_code, error_msg) 
        VALUES (?,?)''', [unicode(return_code), unicode(error_msg)]) 
log_db.commit() 

99出的100倍,它工作得很好,但有時我得到類似的錯誤到:

UnicodeDecodeError錯誤: 'UTF8' 編解碼器不能在位置43進行解碼字節0xce:無效延續字節

編輯:全跟蹤

Traceback (most recent call last): 
    File "openscadfuzzer.py", line 72, in <module> 
    VALUES (?,?)''', [crashed, err_msg.decode('utf-8')]) 
    File "/home/username/workspace/GeneralPythonEnv/openscadfuzzer/lib/python2.7/encodings/utf_8.py", line 16, in decode 
    return codecs.utf_8_decode(input, errors, True) 
UnicodeDecodeError: 'utf8' codec can't decode byte 0xdb in position 881: invalid continuation byte 

這是一個子進程的問題,我使用它運行的應用程序或我的代碼?任何指針將不勝感激(特別是當它涉及subprocess stdout和stderr的正確使用)。

+1

沒有解決方案。只是一個觀察 - 'wait()'和'communicate()'都會等待進程結束。您可以放棄'wait()'調用並執行如下操作:'(out,err,)= process.communicate()return_code = process.returncode' – RedBaron 2013-04-22 08:00:57

+0

您可以給出顯示UnicodeDecodeError發生位置的堆棧跟蹤嗎? – monk 2013-04-22 13:01:01

+0

這也可能是值得指出的Python版本使用,因爲自動解碼/編碼語義在2和3之間不同(和子進程庫也可以) – monk 2013-04-22 13:02:23

回答

2

我的猜測是,這個問題是這樣的呼籲:

unicode(error_msg) 

什麼是ERROR_MSG的類型?我相當肯定,默認情況下,子進程API將返回子程序輸出的原始字節,unicode的調用嘗試通過假設一些編碼(本例中爲utf8)將字節轉換爲字符(代碼點)。

我的猜測是這些字節不是有效的utf8,而是有效的latin1。您可以指定編解碼器字節字符之間轉換:

error_msg.decode('latin1') 

這裏有一個例子是希望演示問題和解決方法:

>>> b'h\xcello'.decode('utf8') 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "/usr/lib/python3.2/encodings/utf_8.py", line 16, in decode 
    return codecs.utf_8_decode(input, errors, True) 
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xce in position 1: invalid continuation byte 

>>> b'h\xcello'.decode('latin1') 
'hÎllo' 

一個更好的解決辦法可能是讓你的孩子的過程輸出UTF8,但是這取決於你的數據庫能夠存儲什麼數據。

+0

我在過去的Windows計算機上遇到過latin1編碼問題,它在Linux環境中經常使用嗎?這是一個流行的開源程序,我很模糊,我不認爲它會從Windows移植過來,但我可能是錯的。我會嘗試你的建議。 – 2013-04-22 14:51:09

+0

如果你在你的shell中運行'echo $ LANG',你會得到什麼? – monk 2013-04-22 17:05:55

+0

$ LANG:en_US.UTF-8。我很確定我明白了。我不檢查我的模糊輸入在任何時候都是有效的utf-8。看到我正在修改人類可讀的文本。 openscad只是在認爲它報告了無效代碼時,將fuzzing創建的任何非UTF-8粘貼到錯誤流中。所以,我想這算作代碼中的一個錯誤? – 2013-04-23 17:17:00

1

你可以在這裏找到很好的子進程教程http://pymotw.com/2/subprocess/及其官方文檔:http://docs.python.org/2/library/subprocess.html,但是從你得到的錯誤格式化看來,它看起來不是你的代碼,而是你的應用程序得到錯誤,你只能看到它,因爲你正在收集輸出。要確認這一點,您可以使用簡單的bash循環在代碼之外運行您的應用程序,以查看是否可以在代碼中再次捕獲錯誤,檢查應用程序的退出代碼 - 當您看到錯誤時應該是不同的比0,如果應用程序正確提供退出代碼。

+0

謝謝,我會在今天晚些時候嘗試,並報告我的結果。這是我懷疑發生的事情。我想我會抓住這個錯誤,並自己把它放在數據庫中,當它發生如下錯誤:「錯誤:程序崩潰與無法解讀的錯誤消息」哈哈。你可能會得到答案,但我想先檢查。 – 2013-04-22 14:44:35