2012-03-29 19 views
27

カスタムコマンドがあります。Popenエラー:[Errno 2]そのようなファイルやディレクトリがありません。

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

しかし、私は自分のシステムがdeactivateのようなコマンドを持っているならば、私はそのエラーに

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 

を取得してみましょうだけで、私は私のサンドボックスvirtualenvの下にこれを実行する必要があります。

+2

おそらく、 'python'はあなたのスクリプトが実行されているときに' PATH'環境変数にありません。 Pythonのフルパス、つまり '/ usr/bin/python'を設定してみてください。 –

+1

達成しようとしていることを説明できますか?私はあなたが 'subprocess'で起動している子シェルがvirtualenv起動スクリプトを"ソース "していないと思っています。親Pythonプロセスから継承されていません。 –

答えて

82

Popenコールに追加パラメータ 'shell = True'を追加してみてください。

+40

私のために働いた、なぜですか? – YMomb

+0

はまだ動作しません – Woeitg

+5

@YMomb: 'deactivate'はシェル関数です。それを実行するには、シェルが必要です。新しいシェルでそれを実行しようとするのは無意味ですが(新しいシェルは 'venv/bin/activate'が呼び出されるまで定義されていないでしょうし、OPは望んでいれば子供は通常親環境を変更できません) 'subprocess.call( 'cd')'がこのようなファイルやディレクトリを持たないのと同じ理由で 'shell = True'を使って修正することができます。 (なぜ、cdはプログラムではないのですか?)(http://unix.stackexchange.com/q/38808/1321) – jfs

3

あなたはプログラムdeactivateへの完全なパスを与えなければなりません。サブプロセスモジュールはそれを見つけることができるはずです。

0

私はそのようなサブプロセスを産卵しています:

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) 

のPython 2.5がそれをサポートしていないので、私は、サブプロセスを使用していませんよ。私はそれを動作させるためにFULLパスを使用しなければなりませんでしたし、あなたもカスタムコマンドへの完全なパスを使用しなければならないと思います。

17

ちょうどメモ。 shell=Trueは、o.p.の正しい解である可能性が高いですが、次のような間違いはありませんでしたが、引数から実行可能ファイルを分割しないと "No such file or directory"エラーが発生する可能性があります。 shell=Trueなし

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 

、popenのには「エコー1」実行可能ファイルが存在しない、実行可能ファイルは、それが失敗した理由である引数の最初の要素であることを期待します。 shell=Trueを追加すると、システムシェルが呼び出され、argsの最初の要素がシェルに渡されます。つまりLinuxではPopen(['echo 1'], shell=True)Popen('/bin/sh', '-c', 'echo 1')に相当し、必要以上にオーバーヘッドになります。 shell=Trueが実際に役に立つ場合は、Popen() documentationを参照してください。

+0

このバージョンのエラーは、Pythonのように文字列リテラルの間にカンマを置くことを忘れた場合に発生しますそれらを連結します: 'sp.Popen(['echo' '1'])#FAILS' –

関連する問題