2011-04-13 22 views
3

我想寫一個Python CGI腳本,它將使用子進程調用sox(一個音頻處理程序)。問題是,當我從sox調用中收到錯誤時,一切都崩潰了,並且我從Apache獲得了「格式錯誤的頭文件」錯誤。如何從python cgi腳本中的子進程中捕獲錯誤?

相關位:

def downsample(in_file, in_location, sox, out_location): 
    """ run sox """ 
... 
    sox = shlex.split(sox) 
    retcode = subprocess.check_call(sox) 
    if not retcode == 0: 
    print '<b>something went wrong in sox: returned error code ' +\ 
      retcode + ', but we are continuing anyway...</b>' 
    """p = subprocess.Popen(sox) 
    if p.stdout: 
    print '<b>something happened in sox: returned ' +\ 
      p.stdout.read() + ', but we will keep going...</b>' 
    if p.stderr: 
    print '<b>something happened in sox: returned ' +\ 
      p.stderr.read() + ', but we will keep going...</b>'""" 
... 

def main(): 
    print "Content-Type: text/html\n\n" 

... 
    downsample(in_file, in_location, command, out_location) 
... 

if __name__ == '__main__': 
    main() 

我使用check_call允許CGI錯誤處理程序打印堆棧跟蹤現在(避免500頁),但我真的很想趕錯誤,自己處理,然後繼續處理腳本。我試圖通過在try_call中包裝check_call來做到這一點:除了CalledProcessError:語句,但這只是再次導致了500頁。那個被註釋掉的部分也不適用於我。

而且在/ var /網絡/的Apache2/error_log中:

Wed Apr 13 10:08:21 2011] [error] [client ::1] sox FAIL formats: can't open input file `/tmp/wavs/haha/f.wav': WAVE: RIFF header not found, referer: http://localhost/~Valkyrie_savage/ 
[Wed Apr 13 10:08:21 2011] [error] [client ::1] malformed header from script. Bad header=\x1f\x8b\b: downsample.py, referer: http://localhost/~Valkyrie_savage/ 

我不明白爲什麼它似乎是運行SOX命令前標題打印。或者,如果是這樣,它爲什麼說頭是畸形的?

回答

1

聽起來像你正在使用緩衝輸出。

如果是這種情況,該命令的輸出將在之前打印HTTP標頭,這樣Web瀏覽器就會變得混亂。

在進行系統調用之前,您可以調用sys.stdout.flush(),以確保輸出緩衝區中的所有標題和html實際上都是打印的。

希望這會有所幫助。

+0

謝謝!這就像一個魅力。 – 2011-05-10 14:30:49

0

您可以使用subprocess.check_call並捕獲CalledProcessError例外。

try: 
    retcode = subprocess.check_call(sox) 
except CalledProcessError: 
    print '<b>something went wrong in sox: returned error code ' +\ 
     retcode + ', but we are continuing anyway...</b>' 
+0

我試過..它實際上也導致了500頁(再次格式錯誤的頭錯誤)。 – 2011-04-13 17:54:23

2
import subprocess 
p = subprocess.Popen(cmd) 
    p.wait() 
    if p.returncode: 
     print "failed with code: %s" % str(p.returncode)