2012-03-29 50 views
27

Tôi có một số lệnh tùy chỉnh.Lỗi Popen: [Errno 2] Không có tệp hoặc thư mục nào như vậy

# works 
subprocess.Popen(['python'], stdout=subprocess.PIPE) 

Nhưng nếu tôi có lệnh hệ thống của riêng tôi như deactivate, tôi nhận được rằng lỗi

Traceback (most recent call last): 
    File "runner2.py", line 21, in <module> 
    main() 
    File "runner2.py", line 18, in main 
    subprocess.Popen(['deactivate',], stdout=subprocess.PIPE) 
    File "/usr/lib/python2.6/subprocess.py", line 633, in __init__ 
    errread, errwrite) 
    File "/usr/lib/python2.6/subprocess.py", line 1139, in _execute_child 
    raise child_exception 
OSError: [Errno 2] No such file or directory 

Hãy để một mình tôi cần phải thực hiện điều này dưới virtualenv sandbox của tôi.

+2

Có thể 'python' không nằm trong biến môi trường' PATH' khi tập lệnh của bạn chạy. Thử đặt đường dẫn đầy đủ thành python, ví dụ: '/ usr/bin/python'. –

+1

Bạn có thể giải thích những gì bạn đang cố gắng hoàn thành không? Tôi nghi ngờ rằng shell con bạn đang khởi chạy với 'subprocess' không" có nguồn gốc "script kích hoạt virtualenv, và nó không được thừa kế từ quá trình Python cha (giả sử đó là nơi bạn đang chạy nó). –

Trả lời

82

Thử thêm thông số bổ sung 'shell = True' vào cuộc gọi Popen.

+40

Làm việc cho tôi, nhưng tại sao? – YMomb

+0

vẫn không hoạt động – Woeitg

+5

@YMomb: 'deactivate' là hàm hệ vỏ. Để chạy nó, bạn cần một trình bao. Mặc dù nó là vô nghĩa để cố gắng chạy nó trong một shell mới (shell mới có lẽ sẽ không có nó được định nghĩa cho đến khi 'venv/bin/activate' được gọi và con thường không thể sửa đổi môi trường cha mẹ của nó anyway nếu OP hy vọng Nó là cùng một lý do tại sao 'subprocess.call ('cd')' tăng lên "Không có tập tin hoặc thư mục như vậy" và nó có thể được cố định bằng cách sử dụng 'shell = True' và nó sẽ bằng nhau pointless.See [Tại sao cd không phải là một chương trình?] (http://unix.stackexchange.com/q/38808/1321) – jfs

3

Bạn phải cung cấp đường dẫn đầy đủ đến chương trình của bạn deactivate và sau đó mô-đun xử lý con sẽ có thể tìm thấy nó.

subprocesses
0

Tôi đang đẻ trứng như thế:

SHUTDOWN_CMD = os.path.sep.join(["c:", "windows", "system32", "shutdown.exe"]) 

def abortShutdown(): 
    os.spawnv(os.P_NOWAIT, SHUTDOWN_CMD, 
     [SHUTDOWN_CMD, '/A']) 
    time.sleep(3) 

tôi không sử dụng tiến trình con từ Python 2.5 không hỗ trợ nó. Tôi đã phải sử dụng đường dẫn đầy đủ để có nó làm việc và tôi đoán bạn cũng phải sử dụng đường dẫn đầy đủ để lệnh tùy chỉnh của bạn.

17

Chỉ cần lưu ý. shell=True có thể là giải pháp đúng cho o.p., vì chúng không mắc lỗi sau, nhưng bạn cũng có thể gặp lỗi "Không có tệp hoặc thư mục" nếu bạn không chia nhỏ tệp thực thi khỏi các đối số của nó.

import subprocess as sp, shlex 
sp.Popen(['echo 1']) # FAILS with "No such file or directory" 
sp.Popen(['echo', '1']) # SUCCEEDS 
sp.Popen(['echo 1'], shell=True) # SUCCEEDS, but extra overhead 
sp.Popen(shlex.split('echo 1')) # SUCCEEDS, equivalent to #2 

Without shell=True, Popen hy vọng thực thi là yếu tố đầu tiên của args, đó là lý do tại sao nó không thành công, không có "echo 1" thực thi. Thêm shell=True gọi trình bao hệ thống của bạn và chuyển phần tử đầu tiên của args vào vỏ. tức là đối với linux, Popen(['echo 1'], shell=True) tương đương với Popen('/bin/sh', '-c', 'echo 1') là chi phí cao hơn mức bạn có thể cần. Xem Popen() documentation cho các trường hợp khi shell=True thực sự hữu ích.

+0

Phiên bản này của lỗi có thể xảy ra nếu bạn quên đặt dấu phẩy giữa các chuỗi ký tự, như Python sẽ nối chúng: 'sp.Popen (['echo' '1']) # FAILS' –