2014-06-19 25 views
18

我需要在本地主機上使用Python運行命令date | grep -o -w '"+tz+"'' | wc -w。我正在使用subprocess模塊,並使用check_output方法,因爲我需要捕獲相同的輸出。啓動子進程時找不到文件錯誤

但是它扔我一個錯誤:

Traceback (most recent call last): 
    File "test.py", line 47, in <module> 
    check_timezone() 
    File "test.py", line 40, in check_timezone 
    count = subprocess.check_output(command) 
    File "/usr/lib/python2.7/subprocess.py", line 537, in check_output 
    process = Popen(stdout=PIPE, *popenargs, **kwargs) 
    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 2] No such file or directory 

請幫我要去錯在何處。我是python新手

+0

你能後會拋出錯誤的行(S)? – wnnmaw

+0

@wnnmaw'subprocess.check_output(command)'其中命令與OP – h4ck3d

+0

中提到的相同如何設置'command'的值? (目前還不清楚OP中的所有單引號和雙引號是如何排列的。)'tz'的價值是什麼? – chepner

回答

38

您必須添加shell=True才能執行shell命令。 check_output正試圖尋找名爲:date | grep -o -w '"+tz+"'' | wc -w的可執行文件,但無法找到它。 (不知道爲什麼你從錯誤消息中刪除了重要信息)。

見的區別:

>>> subprocess.check_output('date | grep 1') 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "/usr/lib/python3.4/subprocess.py", line 603, in check_output 
    with Popen(*popenargs, stdout=PIPE, **kwargs) as process: 
    File "/usr/lib/python3.4/subprocess.py", line 848, in __init__ 
    restore_signals, start_new_session) 
    File "/usr/lib/python3.4/subprocess.py", line 1446, in _execute_child 
    raise child_exception_type(errno_num, err_msg) 
FileNotFoundError: [Errno 2] No such file or directory: 'date | grep 1' 

和:

>>> subprocess.check_output('date | grep 1', shell=True) 
b'gio 19 giu 2014, 14.15.35, CEST\n' 

閱讀有關Frequently Used Arguments文檔有關shell參數以及它如何改變的其他參數的解釋更多的信​​息。


需要注意的是,你應該儘量避免使用shell=True因爲產卵一個外殼可以是一個安全隱患(即使你喜歡彈震,仍然可以執行不執行不受信任的輸入攻擊!)。

子流程模塊的文檔有一小段關於replacing the shell pipeline。 您可以通過產卵蟒蛇兩個進程這樣做並使用subprocess.PIPE

date_proc = subprocess.Popen(['date'], stdout=subprocess.PIPE) 
grep_proc = subprocess.check(['grep', '1'], stdin=date_proc.stdout, stdout=subprocess.PIPE) 
date_proc.stdout.close() 
output = grep_proc.communicate()[0] 

你可以寫一些簡單的包裝功能,可以輕鬆地定義管道:你可以寫的地方

import subprocess 
from shlex import split 
from collections import namedtuple 
from functools import reduce 

proc_output = namedtuple('proc_output', 'stdout stderr') 


def pipeline(starter_command, *commands): 
    if not commands: 
     try: 
      starter_command, *commands = starter_command.split('|') 
     except AttributeError: 
      pass 
    starter_command = _parse(starter_command) 
    starter = subprocess.Popen(starter_command, stdout=subprocess.PIPE) 
    last_proc = reduce(_create_pipe, map(_parse, commands), starter) 
    return proc_output(*last_proc.communicate()) 

def _create_pipe(previous, command): 
    proc = subprocess.Popen(command, stdin=previous.stdout, stdout=subprocess.PIPE) 
    previous.stdout.close() 
    return proc 

def _parse(cmd): 
    try: 
     return split(cmd) 
    except Exception: 
     return cmd 

有了這個:

pipeline('date | grep 1') 

或者:

pipeline('date', 'grep 1') 

或者:

pipeline(['date'], ['grep', '1']) 
+0

謝謝你的工作。 – h4ck3d

+0

僅供參考,某些實現(可能的版本?)不會引發「FileNotFoundError」,而會引發沒有有用信息的「操作系統錯誤」,就像他粘貼一樣。因此,這就是爲什麼他「刪除了基本信息」 – Keozon

+0

「警告:如果與不可信輸入結合使用,傳遞shell = True可能會帶來安全隱患。有關詳細信息,請參閱常用使用參數下的警告。 - https://docs.python.org/2/library/subprocess.html#popen-constructor – Jivan

相關問題