2017-01-25 27 views
5

Tôi có một tập lệnh python liên quan đến nhiều lệnh subprocess.call. Tôi đã viết kịch bản trên máy Mac và nó chạy hoàn hảo. Tôi chỉ cố gắng chạy nó trên Windows và tôi bị bối rối bởi một lỗi.Tại sao lệnh Python subprocess này chỉ hoạt động khi shell = True trên Windows?

Các lệnh sau để gọi ImageMagick trả về "trạng thái thoát 4":

file1 = "D:/Temp/OCR_test/sample/images/crops/time_0011.png" 
subprocess.call(['convert', file1, '-resize', '200%', file1]) 

Thay đổi lệnh để các công việc sau:

subprocess.call(['convert', file1, '-resize', '200%', file1], shell=True) 

Tôi là một chút thận trọng của việc sử dụng shell=True vì các cảnh báo trong tài liệu.
Tôi cũng cần lệnh để làm việc trên cả Mac và Windows, và tôi nhầm lẫn là tại sao nó không hoạt động trên Windows (tôi đã kiểm tra và lệnh này hoạt động khi sử dụng Windows CMD).

Điều thú vị là dòng sau làm việc trước đó trong kịch bản (nơi file, lat_crop1, và croplat biến được định nghĩa):

subprocess.call(['ffmpeg', '-loglevel', 'panic', '-i', file, '-vf', lat_crop1, '-n', croplat]) 

tôi đọc this SO question và thử tất cả những gợi ý (shlex, biến thể của lệnh của tôi, vv ...), nhưng tôi vẫn nhận được kết quả tương tự.

Bất kỳ ai có bất kỳ ý tưởng nào về cách tôi có thể sửa đổi dòng đó để nó có thể hoạt động mà không cần shell=True?

Ngoài ra, "trạng thái thoát 4" có nghĩa là gì? Tôi đã google và đọc rất nhiều tài liệu nhưng không tìm thấy gì về nó.

EDIT: Dựa trên thông tin được cung cấp trong câu trả lời, tôi đã thay đổi thành lệnh không hoạt động thành subprocess.call(['mogrify', file1, '-resize', '200%', file1]) và chạy thành công bằng Python trên Windows. May mắn là ImageMagick cung cấp mogrify thay thế cho convert.

+0

Lệnh 'chuyển đổi' là gì? ImageMagick? – Blorgbeard

+0

Vâng, đó là ImageMagick tôi quên đề cập đến điều đó. Nó hoạt động trong dòng lệnh. – Bird

+0

bạn có thể nhập 'chuyển đổi' từ dòng lệnh không? –

Trả lời

6

Tôi nghi ngờ bạn đang gọi C:\Windows\System32\convert.exe (bộ chuyển đổi phân vùng NTFS/FAT) thay vì imagemagick.

Khi shell=True, con đường tìm convert.bat hoặc convert.cmd kịch bản từ ImageMagick, nhưng không có nó, con đường duy nhất có thể tìm thấy các tập tin .exe, mà là một chương trình hoàn toàn khác nhau, và bạn nhận được lỗi 4: tham số không hợp lệ.

Trong trường hợp cụ thể đó, nó không hoạt động ngay cả khi thực thi, vì "sai" convert nằm trong đường dẫn hệ thống. shell=False chỉ tìm kiếm trong đường dẫn hệ thống (python subprocess Popen environment PATH?). Thật may là một chương trình có tên convert nằm trong đường dẫn hệ thống.

Cố gắng thêm một cách rõ ràng .bat mở rộng như thế này:

subprocess.call(['convert.bat', file1, '-resize', '200%', file1]) 

Để biết được thực thi có thể sẽ được chạy bạn có thể gõ:

where convert 

trong một dấu nhắc lệnh.

Trong trường hợp của bạn (tệp thực thi), điều đó có thể được giải quyết bằng cách chuyển đường dẫn tuyệt đối của tệp thực thi mà bạn muốn chạy.

Một cách khác là sao chép/đổi tên ImageMagick convert thành imconvert. Chương trình nào tự gọi là convert và không mong đợi xung đột?

Hoặc trong trường hợp đó, nó là hợp pháp rời shell=True, với một bình luận thoải mái giải thích rằng Microsoft đã để lại một khó hiểu (và hiếm khi sử dụng chương trình convert trong một đường dẫn hệ thống để chúng ta vấp vào)

Giải pháp là không đẹp, ít nhất có một số.

+2

['CreateProcess'] (https://msdn.microsoft.com/en-us/library/ms682425) luôn tìm kiếm các thư mục hệ thống trước' PATH' và cố gắng thêm ".EXE". Các cmd shell, mặt khác, tìm kiếm riêng của nó 'PATH', và cố gắng thêm phần mở rộng trong' PATHEXT', và sau đó nó gọi là 'CreateProcess' với đường dẫn đầy đủ điều kiện của tập tin mà nó tìm thấy. – eryksun

+0

@eryksun: tìm thấy điều này: http://stackoverflow.com/questions/5658622/python-subprocess-popen-environment-path. Lời giải thích của bạn là giải thích tốt nhất. Tôi đang chỉnh sửa. –

+0

Điều đó thực sự thú vị và tuyệt vời để biết về các chương trình 'chuyển đổi' khác. Thêm đường dẫn đầy đủ trong lệnh 'subprocess' đã làm việc. Cảm ơn vì đã góp ý. Việc thay đổi mô-đun ImageMagick thành 'imconvert' có thể là một ý tưởng hay. Tôi đồng ý rằng đó là lạ họ sẽ sử dụng một tên chung chung. – Bird

Các vấn đề liên quan