OSError: [Errno 2] Không có tệp hoặc thư mục như vậy trong khi sử dụng quy trình con python trong Django


137

Tôi đang cố gắng chạy một chương trình để thực hiện một số cuộc gọi hệ thống bên trong mã Python bằng cách sử dụng subprocess.call()lỗi này:

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

Mã Python thực tế của tôi như sau:

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)

Tôi có thể nhận được một số lời khuyên có liên quan về cách giải quyết điều này?


Câu hỏi được nhân đôi cho câu hỏi này có câu trả lời tốt hơn nhiều. Câu hỏi đó nên được mở lại và câu hỏi này được nhân đôi với nó.
dùng3553031

Câu trả lời:


301

Sử dụng shell=Truenếu bạn đang truyền một chuỗi tới subprocess.call.

Từ tài liệu :

Nếu truyền một chuỗi đơn, hoặc shellphải Truehoặc chuỗi khác chỉ cần đặt tên chương trình sẽ được thực thi mà không chỉ định bất kỳ đối số nào.

subprocess.call(crop, shell=True)

hoặc là:

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

7
Python 3 đưa ra một thông báo lỗi tốt hơn, đặt tên 'tệp' vi phạm, nhưng nó không đưa ra gợi ý rằng shell = True là bắt buộc. Cảm ơn bạn!
AnneTheAgile

14
Xin lưu ý, các tài liệu cũng nêu rõ "việc sử dụng shell=Trueđược khuyến khích mạnh mẽ trong trường hợp chuỗi lệnh được xây dựng từ đầu vào bên ngoài", xem liên kết trong câu trả lời.
hợp lệ

23
@AnneTheAgile: shell=Truekhông bắt buộc. Ngoài ra, bạn không nên sử dụng nó trừ khi cần thiết (xem bình luận của @ hợp lệ). Bạn nên chuyển từng đối số dòng lệnh thành một mục danh sách riêng thay vì sử dụng ['command', 'arg 1', 'arg 2']thay vì "command 'arg 1' 'arg 2'".
jfs

3
@ user3553031 Tôi không khuyến nghị nó hơn các định dạng khác. Tôi chỉ đơn giản chỉ ra thực tế nếu bạn đang sử dụng một chuỗi thì bạn sẽ phải sử dụng shell=True. Các khía cạnh bảo mật nằm ngoài phạm vi của câu hỏi này.
Ashwini Chaudhary

6
@ user3553031 Không phải lúc nào cũng nản lòng, tài liệu nói rõ rằng nó không an toàn khi đầu vào đến từ đầu vào bên ngoài . Nói rằng bạn không nên sử dụng nó bao giờ là vô nghĩa. Và có rất nhiều câu hỏi về quy trình con, sẽ không có ý nghĩa gì khi đề cập đến vấn đề này trong mỗi câu trả lời. Đã có ý kiến ​​về nó từ những người dùng khác và tôi cũng đã chia sẻ liên kết đến tài liệu. Bạn được chào đón để chỉnh sửa câu trả lời của tôi.
Ashwini Chaudhary

5

Không thể upvote vì vậy tôi sẽ đăng lại bình luận @jfs vì tôi nghĩ nó sẽ hiển thị hơn.

@AnneTheAgile: shell = True là không bắt buộc. Ngoài ra, bạn không nên sử dụng nó trừ khi cần thiết (xem bình luận của @ hợp lệ). Thay vào đó, bạn nên chuyển từng đối số dòng lệnh thành một mục danh sách riêng biệt, ví dụ: sử dụng ['lệnh', 'arg 1', 'arg 2'] thay vì "lệnh 'arg 1' 'arg 2'". - jfs 3/03/2015 lúc 10:02


2

No such file or directorycũng có thể được nêu ra nếu bạn đang cố gắng đặt một đối số tệp Popenvới dấu ngoặc kép.

Ví dụ:

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

Trong trường hợp này, bạn cần loại bỏ dấu ngoặc kép.

call_args = ['mv', 'path/to/file with spaces.txt', 'somewhere']
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.