2017-12-14 3 views
1

Ich stelle eine flask-App bereit, in der ein multiprocessing.Process gestartet wird. Innerhalb dieses Prozesses rufe ich einen Shell-Befehl durch subprocess.call() auf. Das Skript läuft gut, wenn auf dem lokalen Host ausgeführt werden, wenn sie mit nginx und gunicorn eingesetzt, verhält sich der Kolben app wie erwartet, bis die Subprozess beginnt, dann erhalte ich das folgende Fehlerprotokoll:Unerwartetes Verhalten beim Aufrufen des Shell-Befehls für eine bereitgestellte Webanwendung

DEBUG:root:start to run command 
DEBUG:root:(<class 'FileNotFoundError'>, FileNotFoundError(2, "No such file or directory: 'java -jar ábsolute/path/to/jar/file') 

           Process(
           target=decode_upload, 
           args=(
             path_to_blf, 
             path_to_dbc_folder, 
             path_to_splitted, 
             path_to_decoder, 
             system_layout, 
             dc_doc, 
             dc_id, 
             file_type, 
           ) 
          ).start() 

Hier ist der rellevant Teil der Funktion.

def decode_file(
    path_to_blf, 
    path_to_dbc_folder, 
    path_to_splitted, 
    path_to_decoder, 
    system_layout=DEFAULT_SYSTEM_LAYOUT): 
    command = "{} {} --blf={}".format(
             SOFTWARE_COMMAND, 
             path_to_decoder, 
             path_to_blf 
    ) 
    for dbc_file_name in DBC_FILE_NAME_LIST: 
     command += " --dbc={}".format(
            os.path.join(
              path_to_dbc_folder, 
              dbc_file_name 
            ) 
     ) 
    command += " --out={}".format(path_to_splitted) 


    logging.debug("start to run command") 
    subprocess.call(command) 
    logging.debug(f) 
    logging.debug("run command end") 

def decode_upload(
         path_to_blf, 
         path_to_dbc_folder, 
         path_to_splitted, 
         path_to_decoder, 
         system_layout, 
         dc_doc, 
         dc_id, 
         file_type): 
    logging.basicConfig(filename='flask.log',level=logging.DEBUG) 
    logging.debug('This message should go to the log file') 

    try: 
     decode_file(
      path_to_blf, 
      path_to_dbc_folder, 
      path_to_splitted, 
      path_to_decoder, 
      system_layout) 
    except: 
     logging.debug(sys.exc_info()) 

Der Prozess schlägt fehl, wenn diese Zeile erreicht wird.

subprocess.call(command) 

Wenn ich versuche, den "Befehl" von der Befehlszeile aufzurufen, funktioniert es ohne ein Problem.

Antwort

1
from subprocess import Popen 
command='your complete command as you paste on cmd' 
p1=Popen(command,Shell=True) 

Dies wird Ihnen helfen, den Befehl als vollständige Zeichenfolge

+0

Hallo, danke für die Antwort. Ja, der Fehler verschwindet, aber der Befehl wird immer noch nicht ausgeführt. Ich fange die stdout von diesem Befehl mit p = subprocess.run ("ls", Shell = True, stdout = PIPE), logging.debug (p.stdout). Aber ich habe eine Nachricht DEBUG: root: b '' ", was nichts in der Protokolldatei bedeutet. Es scheint, der Befehl wurde nicht ausgeführt. –

+0

Was ist der Fehler, den Sie jetzt bekommen –

+0

Nein, Fehler mehr, aber kein Befehl hat Ich habe versucht os.system (Befehl) und nichts passiert, aber wenn ich Befehl im Terminal laufen funktioniert es einwandfrei –

1

Die richtige Lösung zu laufen ist, den Befehl als eine Liste von geparsten Argumente zu übergeben. Sie müssen verstehen, wie die Shell das Quoting und Argument Splitting handhabt, um dies richtig zu machen.

Als schnelle Betrüger,

printf "'%s'\n" your command line here 

in Ihrer Shell sollten Sie eine gute Vorstellung davon, wie die Shell die Argumente erweitert. Zum Beispiel

bash$ printf "'%s'\n" java -jar "/path/complex path with spaces.jar" \* \>\< 
'java' 
'-jar' 
'/path/complex path with spaces.jar' 
'*' 
'><' 

zeigt Ihnen, dass Sie

subprocess.call(['java', '-jar', '/path/complex path with spaces.jar', '*', '><']) 

Anpassung der Code für diese benötigen, so erhalten wir

command = [SOFTWARE_COMMAND, path_to_decoder, '--blf={}'.format(path_to_blf)] 
for dbc_file_name in DBC_FILE_NAME_LIST: 
    command.append("--dbc={}".format(
     os.path.join(path_to_dbc_folder, dbc_file_name))) 
command.append("--out={}".format(path_to_splitted)) 
+1

Siehe auch https://stackoverflow.com/questions/3172470/actual-meaning-of-shell-true-in-subprocess für warum Sie vermeiden möchten, dass "shell = True" – tripleee

+0

Vielen Dank! Es ist sehr hilfreich! –

Verwandte Themen