OSError: [Errno 2] Нет такого файла или каталога при использовании подпроцесса python в Django

137

Я пытаюсь запустить программу, чтобы сделать некоторые системные вызовы внутри кода Python, используя subprocess.call()который выдает следующую ошибку:

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

Мой настоящий код Python выглядит следующим образом:

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)

Могу ли я получить несколько важных советов о том, как решить эту проблему?

Сандип Медераметла
источник
Вопрос, который был дублирован на этот вопрос, имеет гораздо лучший ответ. Этот вопрос должен быть вновь открыт, а этот дублирован на него.
user3553031

Ответы:

301

Используйте, shell=Trueесли вы передаете строку subprocess.call.

Из документов :

Если передается одна строка, либо shellдолжна быть, Trueлибо строка должна просто назвать программу, которая должна быть выполнена, без указания каких-либо аргументов.

subprocess.call(crop, shell=True)

или:

import shlex
subprocess.call(shlex.split(crop))
Ашвини Чаудхари
источник
7
Python 3 дает лучшее сообщение об ошибке, называя нарушающий «файл», но не дает подсказки, что shell = True требуется. Спасибо!
AnneTheAgile
14
Имейте в виду, что в документах также говорится, что "использование shell=Trueне рекомендуется в тех случаях, когда командная строка создается из внешнего ввода", см. Ссылку в ответе.
действует
23
@AnneTheAgile: shell=Trueне требуется. Кроме того, вы не должны использовать его, если это необходимо (см. Комментарий @ valid). Вы должны передавать каждый аргумент командной строки как отдельный элемент списка, например, использовать ['command', 'arg 1', 'arg 2']вместо "command 'arg 1' 'arg 2'".
JFS
3
@ user3553031 Я не рекомендую его для других форматов. Я просто указал на тот факт, что если вы используете строку, то вам придется использовать shell=True. Аспекты безопасности выходят за рамки этого вопроса.
Ашвини Чаудхари
6
@ user3553031 Это не всегда обескураживает, в документации ясно сказано, что это небезопасно, когда вход поступает с внешнего входа . Сказать, что вы никогда не должны использовать это - чепуха. И так много вопросов о подпроцессе, что нет смысла упоминать это в каждом ответе. Об этом уже есть комментарии других пользователей, и я также поделился ссылкой на документацию. Вы можете редактировать мой ответ.
Ашвини Чаудхари
5

Невозможно поднять голос, поэтому я отправлю комментарий @jfs, потому что думаю, что он должен быть более заметным.

@AnneTheAgile: shell = True не требуется. Кроме того, вы не должны использовать его, если это необходимо (см. Комментарий @ valid). Вместо этого вы должны передавать каждый аргумент командной строки как отдельный элемент списка, например, используйте ['command', 'arg 1', 'arg 2'] вместо "command" arg 1 '' arg 2 '". - 3 марта в 10:02

Душан Макшич
источник
2

No such file or directory также может быть вызвано, если вы пытаетесь указать Popen с двойными кавычками.

Например:

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

В этом случае вам необходимо удалить двойные кавычки.

call_args = ['mv', 'path/to/file with spaces.txt', 'somewhere']
Даниил Машкин
источник