OSError: [Errno 2] Keine solche Datei oder kein solches Verzeichnis bei Verwendung des Python-Unterprozesses in Django


137

Ich versuche, ein Programm auszuführen, um einige Systemaufrufe in Python-Code auszuführen, mit subprocess.call()dem der folgende Fehler ausgegeben wird:

Traceback (most recent call last):
      File "<console>", line 1, in <module>
      File "/usr/lib/python2.7/subprocess.py", line 493, in call
      return Popen(*popenargs, **kwargs).wait()
      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

Mein tatsächlicher Python-Code lautet wie folgt:

url = "/media/videos/3cf02324-43e5-4996-bbdf-6377df448ae4.mp4"
real_path = "/home/chanceapp/webapps/chanceapp/chanceapp"+url
fake_crop_path = "/home/chanceapp/webapps/chanceapp/chanceapp/fake1"+url
fake_rotate_path = "/home/chanceapp/webapps/chanceapp.chanceapp/fake2"+url
crop = "ffmpeg -i %s -vf "%(real_path)+"crop=400:400:0:0 "+ "-strict -2 %s"%(fake_crop_path)
rotate = "ffmpeg -i %s -vf "%(fake_crop_path)+"transpose=1 "+"%s"%(fake_rotate_path)
move_rotated = "mv"+" %s"%(fake_rotate_path)+" %s"%(real_path)
delete_cropped = "rm "+"%s"%(fake_crop_path)
#system calls:
subprocess.call(crop)

Kann ich relevante Ratschläge zur Lösung dieses Problems erhalten?


Die Frage, die auf diese Frage dupliziert wurde, hat eine viel bessere Antwort. Diese Frage sollte erneut geöffnet und stattdessen dupliziert werden.
user3553031

Antworten:


301

Verwenden shell=TrueSie diese Option, wenn Sie eine Zeichenfolge an übergeben subprocess.call.

Aus Dokumenten :

Wenn Sie eine einzelne Zeichenfolge übergeben, shellmuss dies entweder sein, Trueoder die Zeichenfolge muss einfach das auszuführende Programm benennen, ohne Argumente anzugeben.

subprocess.call(crop, shell=True)

oder:

import shlex
subprocess.call(shlex.split(crop))

7
Python 3 gibt eine bessere Fehlermeldung aus, indem es die fehlerhafte 'Datei' benennt, aber es gibt keinen Hinweis darauf, dass shell = True erforderlich ist. Danke dir!
AnneTheAgile

14
Beachten Sie, dass in den Dokumenten auch angegeben wird, dass "die Verwendung von in Fällen, in denen die Befehlszeichenfolge aus externen Eingaben shell=Truebesteht, dringend empfohlen wird", siehe Link in der Antwort.
gültig

23
@AnneTheAgile: shell=Trueist nicht erforderlich. Darüber hinaus sollten Sie es nicht verwenden, es sei denn, es ist erforderlich (siehe Kommentar von @ valid). Sie sollten jedes Befehlszeilenargument stattdessen als separates Listenelement übergeben, z. B. ['command', 'arg 1', 'arg 2']anstelle von "command 'arg 1' 'arg 2'".
JFS

3
@ user3553031 Ich empfehle es nicht gegenüber anderen Formaten. Ich habe nur darauf hingewiesen, dass Sie einen String verwenden müssen, wenn Sie ihn verwenden shell=True. Die Sicherheitsaspekte gehen über den Rahmen dieser Frage hinaus.
Ashwini Chaudhary

6
@ user3553031 Es wird nicht immer davon abgeraten, die Dokumentation besagt eindeutig, dass es nicht sicher ist, wenn die Eingabe von einer externen Eingabe kommt . Zu sagen, du solltest es niemals benutzen, ist Unsinn. Und es gibt so viele Fragen zu Teilprozessen, dass es keinen Sinn macht, dies in jeder Antwort zu erwähnen. Es gibt bereits Kommentare von anderen Benutzern und ich habe den Link zur Dokumentation ebenfalls geteilt. Gerne können Sie meine Antwort bearbeiten.
Ashwini Chaudhary

5

Kann nicht upvoten, also werde ich @ jfs Kommentar erneut posten, weil ich denke, dass es sichtbarer sein sollte.

@AnneTheAgile: shell = True ist nicht erforderlich. Darüber hinaus sollten Sie es nicht verwenden, es sei denn, es ist erforderlich (siehe Kommentar von @ valid). Sie sollten jedes Befehlszeilenargument stattdessen als separates Listenelement übergeben, z. B. ['Befehl', 'Argument 1', 'Argument 2'] anstelle von "Befehl 'Argument 1' 'Argument 2'". - JFS 3. März 15 um 10:02 Uhr


2

No such file or directorykann auch ausgelöst werden, wenn Sie versuchen, ein Dateiargument in Popendoppelte Anführungszeichen zu setzen.

Beispielsweise:

call_args = ['mv', '"path/to/file with spaces.txt"', 'somewhere']

In diesem Fall müssen Sie doppelte Anführungszeichen entfernen.

call_args = ['mv', 'path/to/file with spaces.txt', 'somewhere']
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.