2016-04-07 17 views
1

私はpppプログラムによって呼び出されたPP30接続が確立されたときに実行されているPythonスクリプトを持っています。 Pythonスクリプトは、基本的には、コマンドラインプログラムを呼び出し、結果を解析し、それを返します:なぜPythonのsubprocess.check_outputが機能するには、shell = Trueが必要ですか?

import subprocess 

result = subprocess.check_output(["fw_printenv", "serialnr"]) 
result = # some operation 
return result 

私は、コマンドライン(例えばpython script.py)から手動でPythonスクリプトを実行すると、このコードは100%正常に動作しますが、それはdoesnのif-upからPPPによって実行されているときは全く動作しません。 subprocess.check_outputが呼び出されたときに例外が発生します:[Errno 2] No such file or directory: 'fw_printenv'

私は唯一の私は、コードを変更した場合、それは仕事を得ることができます:

result = subprocess.check_output("fw_printenv serialnr", shell=True) 

なぜ?

+4

シェルを使用すると、システムのPATH変数が使用されています。これは、最初のバージョンで実行可能ファイルが見つからない –

答えて

3

シェルがTrueの場合、指定されたコマンドはシェルを介して実行されます。これは、主に、ほとんどのシステムシェルで提供される拡張された制御フローに対してPythonを使用していて、シェルパイプ、ファイル名ワイルドカード、環境変数の拡張などの他のシェル機能への便利なアクセスを必要とする場合に便利です。ユーザーのホームディレクトリ。しかし、Python自体は多くのシェルのような機能(特にglob、fnmatch、os.walk()、os.path.expandvars()、os.path.expanduser()、およびshutil)の実装を提供していることに注意してください。

環境変数(UNIXシステム下/usr/bin/含む可能な経路を含む、notabily PATH)をバイナリへのパスを取得するために必要です。 その他、fw_printenvは、accessed by absolute pathとすることができます。

3

絶対パスを使用:

result = subprocess.check_output(["/full/path/to/fw_printenv", "serialnr"]) 

同じあなたはcronとウェブサーバを経由して実行するもののために行きます。

shell=Trueは明らかにシェルを開きますが、あまり明らかに、端末で手動でスクリプトを実行しているかのように、すべての環境変数(例:PATH)も設定します。 shell=Trueを削除し、代わりに絶対パスを使用することは、おそらく最も効果的な選択です(これは私が思う)。 subprocess documentationから

関連する問題