2013-11-22 14 views
6

私はsubprocess.Popenモジュールで別のpythonスクリプトを呼び出すスクリプトを持っています。私はそれが@wilberforce &をコーミングによって動作するようになったSubprocess.Popenに変数を渡す

:私は変数に格納された引数(複数可)

servers[server]['address'] 
servers[server]['port'] 
servers[server]['pass'] 

を持っているのでしかし、私は

p = subprocess.Popen(["python mytool.py -a ", servers[server]['address'], "-x", servers[server]['port'], "-p", servers[server]['pass'], "some additional command"], shell=True, stdout=subprocess.PIPE) 

は、回避策のコマンドを実行することができません@ ciphorさんの答えですが少し修正して

command = "python mytool.py -a %s -x %s -p %s some additional command" % (servers[server]['address'], servers[server]['port'], servers[server]['pass']) 
p = subprocess.Popen(command , shell=True, stdout=subprocess.PIPE) 

二重引用符で複数の変数を追加した場合、動作が停止します。最大2個の変数を取り、さらにブレークします。

お返事いただいた皆様に感謝します。

+1

変数を使用して、コマンドである文字列を作成するか、引数のリストとして渡します。 – beroe

答えて

5

落下shell=TrueThe arguments to Popen() are treated differently on Unix if shell=True

import sys 
from subprocess import Popen, PIPE 

# populate list of arguments 
args = ["mytool.py"] 
for opt, optname in zip("-a -x -p".split(), "address port pass".split()): 
    args.extend([opt, str(servers[server][optname])]) 
args.extend("some additional command".split()) 

# run script 
p = Popen([sys.executable or 'python'] + args, stdout=PIPE) 
# use p.stdout here... 
p.stdout.close() 
p.wait() 

注意警告in the docsによって記載されたように、外部入力とコマンドのためshell=Trueを通過する、セキュリティ上の危険であること。

2

subprocess.Popenに電話すると、コマンドを実行するための文字列またはリストを渡すことができます。リストを渡す場合、項目は特定の方法で分割する必要があります。あなたのケースでは

、あなたはこのようにそれに何かを分割する必要があります:あなたはリストを渡す場合、Popenはすでに(言葉に値をコマンドラインを分割していることを前提としているため

command = ["python", "mytool.py", "-a", servers[server]['address'], 
      "-x", servers[server]['port'], 
      "-p", servers[server]['pass'], 
      "some", "additional", "command"] 
p = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE) 

これであるだろう最終的にはsys.argvになります)、そうする必要はありません。

「python mytool.py -a」というバイナリを実行しようとしますが、それはあなたが意味するものではありません。

これを修正する別の方法は、すべての単語を文字列に結合することです(Popenは分割されます - subprocess.list2cmdlineを参照)。しかし、可能であれば、リストバージョンを使う方が良いです。コマンドラインが引用符で囲まれていなくても、コマンドラインがどのように分割されるかを簡単に制御できます。

+0

私は出力を保存するために使用する変数ですが、それは空です(私は実行されていないと思います)。 – GaNi

+0

あなたは、あなたがp。stdout、出力はありませんか?コマンドが実行されていないためです。 – babbageclunk

+0

実際には、シェル= Trueがおそらくここで水を混乱させるでしょう - あなたがグロビングを使っていない限り(ファイルのリストを展開するなど)、それをオフにするのが一番です。 – babbageclunk

1

あなたは文字列全体にコマンドを連結する必要があります

p = subprocess.Popen("python mytool.py -a " + servers[server]['address'] + " -x " + servers[server]['port'] + " -p " + servers[server]['pass'] + " some additional command", shell=True, stdout=subprocess.PIPE) 
+0

出力を変数に保存しましたが、実行中のスクリプトの出力やトレースはありません。それを確認するために直接エラー出力されることがありますか? – GaNi

+0

「stderr = subprocess.PIPE」も追加 – ciphor

1

あなたの問題を最初Popen引数のタイプstrに。それをlistに置き換えてください。コードが動作することができます下:それはパラメータをシステム-依存するため

address = servers[server]['address'] 
port = servers[server]['port'] 
pass = servers[server]['pass'] 

command = "python mytool.py -a %s -x %d -p %s some additional command" % (address, port, pass) 
p = subprocess.Popen(command.split(), shell=True, stdout=subprocess.PIPE) 
#     ^^^^^^^^^^^^^^^ 

さらにあなたは、shellで遊ぶことができます。

+0

これまでと同様の問題がありましたが、今解決しました。ありがとう:) – GaNi