web-dev-qa-db-ja.com

Python:Shell = Falseが機能しないサブプロセス呼び出し

Pythonスクリプトを使用してJava仮想マシンを呼び出しています。次のコマンドは機能します。

subprocess.call(["./rvm"], Shell=False)  # works
subprocess.call(["./rvm xyz"], Shell=True) # works

だが、

subprocess.call(["./rvm xyz"], Shell=False) # not working

動作しません。 Pythonドキュメント 回避するためのアドバイスShell=True

14
Tanay

コマンドを個別の文字列に分割する必要があります。

subprocess.call(["./rvm", "xyz"], Shell=False)

文字列はShell=Trueの場合に機能しますが、Shell=Falseの場合は引数のリストが必要です

shlex モジュールは、より複雑なコマンドや入力の処理に役立ちますが、以下について学ぶことをお勧めします。

import shlex

cmd = "python  foo.py"
subprocess.call(shlex.split(cmd), Shell=False)

shlex tut

29

Shell=Trueを使用する場合、これは正当です。そうでない場合、標準ライブラリから削除されます。ドキュメントはそれを避けるように言っていません、それは 言う

信頼できないソースからのサニタイズされていない入力を組み込んだシェルコマンドを実行すると、プログラムがシェルインジェクションに対して脆弱になります。これは重大なセキュリティ上の欠陥であり、任意のコマンドが実行される可能性があります。このため、コマンド文字列が外部入力から作成されている場合は、Shell=Trueの使用を強くお勧めしません。

ただし、ユーザー入力からコマンドを作成していない場合、コマンドは一定であるため、コードにはシェルインジェクションの問題は発生しません。シェルが実行する内容を制御できます。コード自体が悪意のないものでなければ、安全です。

シェル注入の例

シェルインジェクションが非常に悪い理由を説明するために、これは ドキュメント で使用されている例です。

>>> from subprocess import call
>>> filename = input("What file would you like to display?\n")
What file would you like to display?
non_existent; rm -rf / #
>>> call("cat " + filename, Shell=True) # Uh-oh. This will end badly...

編集

質問を編集するために提供した追加情報を使用して、 Padraic の回答に固執します。 Shell=Trueは必要な場合にのみ使用してください。

6
enrico.bacis

Enrico.bacisの回答に加えて、プログラムを呼び出す方法は2つあります。 Shell=Trueを使用して、完全なコマンド文字列を指定します。 Shell=Falseを使用して、リストを作成します。

*.jpg2> /dev/nullのようなシェルトリックを行う場合は、Shell=Trueを使用します。しかし、一般的にはShell=Falseをお勧めします-エンリコが言ったようにそれはより耐久性があります。

ソース

import subprocess
subprocess.check_call(['/bin/echo', 'beer'], Shell=False)
subprocess.check_call('/bin/echo beer', Shell=True)

出力

beer
beer
4
johntellsall

ファイル名ディレクトリを使用する代わりに、環境変数へのpythonパスを追加した場合は、その前にWord pythonを追加します。不明な場合は、新しいバージョンのpythonを使用している場合は、いつでもpythonインストーラーを再実行できます。

これが私が意味することです:

import subprocess
subprocess.Popen('python "C:/Path/To/File/Here.py"')
0
Krohnus Melavea