2014-07-16 41 views
3

在Linux上的apache2 + mod_wsgi下運行的代碼有時產生以下輸出。使用短命令(〜125個字符)間歇性地「OSError:[Errno 7]參數列表太長」

notes.py 
      cmd_list = [ 
        'abc_generate_pdf', 
        '--cdb-url-prefix', model.config('cdb_url_prefix'), 
        '--request-cid', request_cid, 
      ] 
      log.info("About to run: {!r}".format(cmd_list)) 
      subprocess.Popen(cmd_list) 
... 
2014-07-16 11:03:44,779 INFO  pid:17925,140353357215488 abc.webapp.check.notes:198:approval_revoke About to run: ['abc_generate_pdf', '--cdb-url-prefix', 'xxxxdev', '--request-cid', u'xxxxx_xxx_2014-07-15_16.12.50.108807_685932a62c7c6226987acdeda367dbc3'] 
2014-07-16 11:03:45,250 ERROR pid:17925,140353357215488 abc.webapp.check.notes:208:approval_revoke Unknown error; approval not updated. 
Traceback (most recent call last): 
    File "/home/abc/abc/webapp/check/notes.py", line 199, in approval_revoke 
    subprocess.Popen(cmd_list) 
    File "/usr/lib/python2.7/subprocess.py", line 679, in __init__ 
    errread, errwrite) 
    File "/usr/lib/python2.7/subprocess.py", line 1249, in _execute_child 
    raise child_exception 
OSError: [Errno 7] Argument list too long 

輸出已被略微匿名,但字符數仍然準確。

這個問題似乎發生在Web服務器運行了很長時間後,隨着重新啓動而消失,但很難精確地確定觸發器的可能性。

爲什麼我得到一個錯誤,我能做些什麼來防止它?

這個問題非常類似於Python OSError no 7 (Argument list too long) in linux,它沒有一個滿意的答案。

編輯:我應該注意,問題也發生在純python werkzeug服務器下。

+0

是否值得用'shell = True'進行調試? – mdurant

+0

可能。我希望在使用band-aids之前瞭解這個問題,但也許這會導致更詳細的錯誤。我會給它一個機會,雖然可能需要一段時間才能讓一個過程變得足夠老化,以便再次展示問題。 –

回答

6

我們有一個類似的問題,也困擾了我們一段時間。今天,我們找到了根本原因。

錯誤信息有點誤導,它不是命令行的「參數」太長,它實際上是與命令一起傳遞的操作系統環境。在這種情況下,Python os.environ。在我們的代碼庫,有一行代碼:

os.environ['PATH'] = ':'.join([os.environ['PATH'], self.clitoolsdir])

這是一類的__init__()的一部分。每當創建新對象時,os.environ變得更長,最終變得「太長」。

+0

非常感謝發佈此解決方案! –

0

這聽起來像是內存泄漏。試想一下:

  1. 是在Popen呼叫正常關閉,與輸出消耗?

    我這種風格的粉絲:

    subprocess.check_call('mycommand') 
    
  2. 通過Python OSError no 7 (Argument list too long) in linux的建議,當你strace程序,會發生什麼?這個問題和相關問題聽起來非常相似。