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)

Чи можу я отримати відповідні поради щодо вирішення цього питання?


На питання, яке було дубльовано на це питання , є набагато краща відповідь. Це питання слід повторно відкрити, а це замість нього дублювати.
користувач3553031

Відповіді:


301

Використовуйте, shell=Trueякщо ви передаєте рядок subprocess.call.

З документів :

Якщо передається одна рядок, вона shellповинна бути Trueабо інакше рядок повинен просто називати програму, яку потрібно виконати, не вказуючи жодних аргументів.

subprocess.call(crop, shell=True)

або:

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

7
Python 3 дає краще повідомлення про помилку, називаючи обраний "файл", але не дає підказки, що оболонка = 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 Це не завжди перешкоджає, документація чітко говорить, що це не безпечно, коли вхід надходить із зовнішнього входу . Казати, що ви ніколи не повинні використовувати це - нісенітниця. А питань про підпроцеси так багато, що немає сенсу згадувати про це у кожній відповіді. Про нього вже є коментарі від інших користувачів, і я поділився посиланням на документацію. Ви можете редагувати мою відповідь.
Ashwini Chaudhary

5

Не можу подати заявку, тому я репостую коментар @jfs, тому що я думаю, що це повинно бути помітнішим

@AnneTheAgile: shell = Істинно не потрібно. Більше того, ви не повинні використовувати його, якщо це не потрібно (див. Коментар @ valid). Ви повинні передавати кожен аргумент командного рядка як окремий елемент списку замість, наприклад, використовувати ['command', 'arg 1', 'arg 2'] замість "command 'arg 1' 'arg 2'". - jfs 3 березня 15 р. О 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']
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.