OSError: [Errno 2] ไม่มีไฟล์หรือไดเร็กทอรีดังกล่าวขณะใช้กระบวนการย่อย python ใน Django


143

ฉันพยายามเรียกใช้โปรแกรมเพื่อทำการเรียกระบบบางอย่างภายในรหัส 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

คำตอบ:


312

ใช้ถ้าคุณผ่านสายไปยังshell=Truesubprocess.call

จากเอกสาร :

หากผ่านสายเดียวทั้งshellต้องTrueหรืออื่นสตริงก็ต้องตั้งชื่อโปรแกรมที่จะดำเนินการโดยไม่ต้องระบุข้อโต้แย้งใด ๆ

subprocess.call(crop, shell=True)

หรือ:

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

8
Python 3 ให้ข้อความแสดงข้อผิดพลาดที่ดีกว่าโดยตั้งชื่อ 'ไฟล์' ที่ละเมิด แต่ไม่ได้ให้คำใบ้ว่าจำเป็นต้องใช้ shell = True ขอบคุณ!
AnneTheAgile

14
โปรดทราบว่าเอกสารยังรัฐ "ใช้shell=Trueเป็นกำลังใจอย่างมากในกรณีที่สตริงคำสั่งจะถูกสร้างขึ้นมาจากสัญญาณจากภายนอก" ดูการเชื่อมโยงในคำตอบ
ใช้ได้ใน

24
@AnneTheAgile: shell=Trueไม่จำเป็น ยิ่งไปกว่านั้นคุณไม่ควรใช้มันจนกว่าจะมีความจำเป็น (ดูความคิดเห็นของ @ valid) คุณควรส่งอาร์กิวเมนต์บรรทัดคำสั่งแต่ละรายการเป็นรายการแยกต่างหากแทนเช่นใช้['command', 'arg 1', 'arg 2']แทน"command 'arg 1' 'arg 2'".
jfs

3
@ user3553031 ฉันไม่แนะนำให้ใช้กับรูปแบบอื่น shell=Trueผมได้ชี้ให้เห็นเพียงแค่ออกจากความจริงที่ว่าคุณกำลังใช้สตริงแล้วคุณจะต้องใช้ ประเด็นด้านความปลอดภัยอยู่นอกเหนือขอบเขตของคำถามนี้
Ashwini Chaudhary

6
@ user3553031 มันไม่ได้เป็นกำลังใจเสมอเอกสารชัดเจนว่าจะไม่ปลอดภัยเมื่อมีการป้อนข้อมูลจะมาจากการป้อนข้อมูลภายนอก การบอกว่าคุณไม่ควรใช้มันเป็นเรื่องไร้สาระ และมีคำถามมากมายเกี่ยวกับกระบวนการย่อยจึงไม่สมเหตุสมผลที่จะพูดถึงสิ่งนี้ในทุกคำตอบ มีความคิดเห็นเกี่ยวกับเรื่องนี้จากผู้ใช้รายอื่นอยู่แล้วและฉันได้แชร์ลิงก์ไปยังเอกสารประกอบด้วย คุณสามารถแก้ไขคำตอบของฉันได้
Ashwini Chaudhary

7

ไม่สามารถโหวตได้ดังนั้นฉันจะโพสต์ความคิดเห็นของ @jfs ใหม่เพราะฉันคิดว่ามันควรจะมองเห็นได้มากขึ้น

@AnneTheAgile: shell = True ไม่จำเป็น ยิ่งไปกว่านั้นคุณไม่ควรใช้มันจนกว่าจะมีความจำเป็น (ดูความคิดเห็นของ @ valid) คุณควรส่งอาร์กิวเมนต์บรรทัดคำสั่งแต่ละรายการเป็นรายการแยกกันแทนเช่นใช้ ['command', 'arg 1', 'arg 2'] แทน "command 'arg 1' 'arg 2'" - jfs 3 มี.ค. 58 เวลา 10:02 น


5

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']
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.