2014-06-19 5 views
18

Ich muss den Befehl date | grep -o -w '"+tz+"'' | wc -w mit Python auf meinem localhost ausführen. Ich benutze subprocess Modul für die gleiche und mit der check_output Methode, wie ich die Ausgabe für die gleiche erfassen muss.Datei nicht gefunden Fehler beim Starten eines Subprozesses

Allerdings ist es mir einen Fehler werfen:

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 

Bitte helfen, wo ich falsch gehe. Ich bin neu in Python

+0

Können Sie die Linie Post (s), die den Fehler auslöst? – wnnmaw

+0

@wnnmaw 'subprocess.check_output (Befehl)' wo Befehl ist wie in OP erwähnt – h4ck3d

+0

Wie stellen Sie den Wert von 'Befehl' ein? (Es ist nicht klar, wie alle einfachen und doppelten Anführungszeichen in der OP angeordnet sind.) Was ist der Wert von 'tz'? – chepner

Antwort

38

Sie müssen shell=True hinzufügen, um einen Shell-Befehl auszuführen. check_output versucht, eine ausführbare Datei namens: date | grep -o -w '"+tz+"'' | wc -w zu finden, und er kann es nicht finden. (keine Ahnung, warum Sie die wesentlichen Informationen aus der Fehlermeldung entfernt haben).

Sehen Sie den Unterschied zwischen:

>>> 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' 

Und:

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

Lesen Sie die Dokumentation über die Frequently Used Arguments für weitere Informationen über die shell Argument und wie sie die Auslegung der anderen Argumente ändert.


Beachten Sie, dass Sie versuchen sollten, mit shell=True zu vermeiden, da eine Shell Laichen kann ein Sicherheitsrisiko sein (auch wenn Sie nicht nicht vertrauenswürdigen Eingaben Angriffe ausführen kann wie Shellshock noch durchgeführt werden kann!).

Die Dokumentation für das Subprozessmodul enthält einen kleinen Abschnitt über replacing the shell pipeline. Sie können durch das Laichen, die beiden Prozesse in Python so tun und verwenden 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] 

Sie können einige einfache Wrapper-Funktion schreiben, um leicht Pipelines zu definieren:

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 

In diesem Ort können Sie schreiben:

pipeline('date | grep 1') 

Oder:

pipeline('date', 'grep 1') 

Oder:

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

Danke das hat funktioniert. – h4ck3d

+0

Just FYI, bestimmte Implementierungen (möglicherweise Versionen?) Nicht ein "FileNotFoundError", sondern ein "OS Error" ohne hilfreiche Informationen, gerade als er eingefügt. Deshalb hat er "die wesentlichen Informationen entfernt" – Keozon

+0

"Warnung: Passing Shell = True kann ein Sicherheitsrisiko sein, wenn mit nicht vertrauenswürdigen Eingabe kombiniert. Siehe die Warnung unter Häufig verwendete Argumente für Details." - https://docs.python.org/2/library/subprocess.html#popen-constructor – Jivan

Verwandte Themen