2014-07-16 30 views
5

tôi muốn gọi là "chuyển đổi" tiện ích từ ImageMagick từ kịch bản Python của tôi sử dụng Popen, như vậy:Popen với thực thi mâu thuẫn/path

Popen(["convert", input_path, "-flop", output_file_path]) 

(Ví dụ trên chỉ đơn giản là đảo ngược hình ảnh theo chiều ngang)

Vấn đề là khi tôi chạy tập lệnh trong Windows, nó gọi nhầm tiện ích convert.exe đi kèm với Windows để chuyển đổi phân vùng FAT thành NTFS! (nằm trong \ Windows \ system32)

Bây giờ, nếu tôi mở một dấu nhắc lệnh ngẫu nhiên tại bất kỳ thư mục nào khác ngoài system32 và nhập "chuyển đổi", nó sẽ chạy tệp thực thi ImageMagick một cách chính xác. Vì vậy, điều này ngụ ý rằng Popen được tự động tìm kiếm trong system32. Làm thế nào tôi có thể làm cho nó không nhìn trong system32, và chạy đúng thực thi?

+0

Bạn đã thử xóa đường dẫn đến system32 từ 'sys.path' chưa? –

+1

i) system32 không nằm trong 'sys.path' ii)' Popen' không tìm trong 'sys.path'. – Daniel

+0

'Popen' bắt đầu từ thư mục hiện tại. Biến môi trường 'PATH' của bạn là gì? – Daniel

Trả lời

7

Tìm kiếm chương trình không nhỏ. Tôi muốn chỉ định đường dẫn đầy đủ cho tệp thực thi convert.exe một cách rõ ràng.

subprocess sử dụng CreateProcess on Windows that looks in system32 directory even before any other directory in %PATH%:

... Nếu tên tập tin không chứa một phần mở rộng, .exe được nối. Do đó, nếu phần mở rộng tên tệp là .com, thông số này phải là bao gồm phần mở rộng .com. Nếu tên tệp kết thúc bằng dấu chấm (.) Với không có đuôi, hoặc nếu tên tệp có chứa đường dẫn, .exe không phải là được nối thêm. Nếu tên tập tin không chứa đường dẫn thư mục, hệ thống tìm kiếm các tập tin thực thi theo trình tự sau:

  1. Thư mục mà từ đó các ứng dụng nạp.
  2. Thư mục hiện tại cho quy trình gốc.
  3. Thư mục hệ thống Windows 32 bit. Sử dụng hàm GetSystemDirectory để lấy đường dẫn của thư mục này.
  4. Thư mục hệ thống Windows 16 bit. Không có hàm nào có được đường dẫn của thư mục này, nhưng nó được tìm kiếm. Tên của thư mục này là System.
  5. Thư mục Windows. Sử dụng hàm GetWindowsDirectory để lấy đường dẫn của thư mục này.
  6. Các thư mục được liệt kê trong biến môi trường PATH. Lưu ý rằng chức năng này không tìm kiếm đường dẫn cho mỗi ứng dụng được chỉ định bởi khóa đăng ký Đường dẫn ứng dụng. Để bao gồm đường dẫn ứng dụng này trong chuỗi tìm kiếm, hãy sử dụng hàm ShellExecute.

Do đó convert tương đương với convert.exe trong trường hợp này. Đầu tiên nó trông vào một thư mục có chứa sys.executable ví dụ: C:\Python27. Sau đó, trong thư mục hiện tại: nơi bạn bắt đầu kịch bản Python từ. Sau đó, trong system32 nơi tìm thấy convert.exe (tiện ích hệ thống tệp, không phải hình ảnh tưởng tượng).

Bạn có thể thử xóa thư mục system32 khỏi os.environ['PATH'] nó có thể (?) Ngăn chặn kiểm tra nó: Popen(cmd, env=no_system32_environ) nhưng nó là mong manh (tồi tệ hơn đường dẫn rõ ràng).

Có một vấn đề liên quan về Python lỗi tracker: "Subprocess picks the wrong executable on Windows."


cmd.exe (vỏ) sử dụng thuật toán khác nhau. Xem How does Windows locate files input in the shell?

Nếu bạn đặt shell=True sau đó trình tự tìm kiếm cho convert chương trình:

  1. convert không phải là một lệnh shell nội
  2. không có con đường rõ ràng, vì vậy việc tìm kiếm tiếp tục
  3. tìm kiếm hiện tại thư mục
  4. tìm kiếm mỗi thư mục được chỉ định bởi biến môi trường PATH, theo thứ tự được liệt kê

%PATHEXT% xác định tiện ích mở rộng tệp nào được chọn và theo thứ tự nào, ví dụ: convert.com, convert.exe, convert.bat, conversion.cmd nếu %PATHEXT%.com;.exe;.bat;.cmd.

+1

FYI, trong Vista và sau đó cả hai 'CreateProcess' và' SearchForExecutable' chức năng trong cmd.exe gọi ['NeedCurrentDirectoryForExePath'] (https://msdn.microsoft.com/en-us/library/ms684269). Nếu bạn đặt biến môi trường 'NoDefaultCurrentDirectoryInExePath', nó sẽ ngăn tìm kiếm thư mục hiện tại. – eryksun

+1

Bạn cũng có thể lưu ý rằng, sau khi tìm tập tin, cmd.exe đầu tiên thử 'CreateProcess' (bất kể phần mở rộng của tập tin) và sau đó thử' ShellExecuteEx', cho phép thực thi các kiểu tập tin tùy ý. Lệnh 'start' của cmd tương tự nhưng gọi' ShellExecuteEx' ngay cả khi không tìm thấy tệp nào, chẳng hạn như các lệnh 'App Paths' đã đăng ký (ví dụ' start/b/w python.exe' sẽ hoạt động ngay cả khi python.exe không phải là tìm thấy, vì trình cài đặt nên đã đăng ký lệnh mặc định cho "python.exe"). – eryksun

2

Là một cách tiếp cận hoàn toàn khác, bạn có thể muốn thử ra PythonMagick, một trình bao bọc Python cho ImageMagick. Bằng cách này bạn có thể truy cập các chức năng của convert từ bên trong Python, và bạn sẽ không phải sinh ra các quy trình bên ngoài.

0

Chỉ cần tự mình điều hành. Chạy một script php trong một shell có quyền truy cập vào shell $ PATH, trong khi chạy bên trong Apache thì không (ít nhất không phải là $ PATH với dll Cygwin/exe).

Thứ hai, sử dụng ký hiệu Windows gốc C:/dir/subdir/pgm trong php khi trên nền tảng cửa sổ và bạn sẽ nhận được những gì bạn mong đợi.

Vì vậy, mã đa nền tảng cần phải chuyển/trường hợp đường dẫn và sau đó tham chiếu đến quyết định.

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