2016-03-30 7 views
4

私はPythonでbashコマンドを呼び出すためにsubprocessを使用しています。シェルが表示しているものとは異なる戻りコードを取得しています。 "lsのは/ dev/DSK &>は/ dev/nullに" 送ると

import subprocess 
def check_code(cmd): 
    print "received command '%s'" % (cmd) 
    p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) 
    p.wait() 
    print "p.returncode is '%d'" % (p.returncode) 
    exit() 
    if p.returncode == 0: 
     return True 
    else: 
     return False 
    #End if there was a return code at all 
#End get_code() 

、check_codeは "エコー$?" 0を返しますが、端末に「2」が生成されます。

Welcome to Dana version 0.7 
Now there is Dana AND ZOL 

received command 'ls /dev/dsk &> /dev/null' 
p.returncode is '0' 
[email protected]:~# ls /dev/dsk &> /dev/null 
[email protected]:~# echo $? 
2 
[email protected]:~# 

ここで何が起こっているのか分かりますか?

+1

私はあなたが 'ls'のシェルではなくシェルのリターンコードを見ていると思います。 – jtbandes

+0

'p.wait()'の戻り値も間違っていますか? –

+0

'shell = True'を使うのはお勧めできません。特に、信頼できないユーザー入力がある場合。 –

答えて

3

subprocess.Popenによると、Pythonスクリプトで使用されるシェルはshです。このシェルはBashとは対照的に、POSIX規格であり、簡略リダイレクト&> /dev/nullのようないくつかの非標準機能を備えています。 sh(Bourneシェル)は、このシンボルを「バックグラウンドで実行し、stdoutを/ dev/nullにリダイレクトする」と解釈します。

あなたsubprocess.Popenは、独自のバックグラウンドでlsを実行shを開くので、shの戻り値は、あなたのPythonとBashの行動をしたい場合は、この場合には0

である、代わりにlsの使用されているが、私はPython自体を(おそらく再コンパイルして)再構成する必要があるかもしれないと考えてください。 shという構文を使用するのが簡単です(ls /dev/dsk 2> /dev/null)。

-1

subprocess.Popen(cmd, shell=True)としてcmdを文字列として使用しています。

これは、サブプロセスが引数で/bin/shフードの下でコールすることを意味します。あなたはshellの終了コードを返しています。

コマンドのコードを実際に終了する必要がある場合は、リストに分割してshell=Falseを使用してください。

subprocess.Popen(['cmd', 'arg1'], shell=False)

+3

あなたが '>/dev/null'を必要とするなら、シェルを避けることはできません。また、シェルの終了コードは、最後に実行されたコマンドの終了コードでなければなりません。 –

0

xi_の提案に続いて、私は宇宙線引きフィールドに、コマンドを分割し、それは「&>」を実行に失敗し、「を/ dev/null」。私はそれらを削除し、それは働いた。

次に、 "&/dev/null"を付けずにすべてのコマンドをテストしてみました。 "&/dev/null"を追加すると、何とかサブプロセスがオフになっているようです。

Welcome to Dana version 0.7 
Now there is Dana AND ZOL 

received command 'cat /etc/fstab' 
p.wait() is 0 
p.returncode is '0' 

received command 'cat /etc/fstabb' 
p.wait() is 1 
p.returncode is '1' 

received command 'cat /etc/fstab &> /dev/null' 
p.wait() is 0 
p.returncode is '0' 

received command 'cat /etc/fstabb &> /dev/null' 
p.wait() is 0 
p.returncode is '0' 
[email protected]:~# cat /etc/fstab &> /dev/null 
[email protected]:~# echo $? 
0 
[email protected]:~# cat /etc/fstabb &> /dev/null 
[email protected]:~# echo $? 
1 
[email protected]:~# 

私はSTDERRから、画面上の出力を見ていたので、私はもともとコールに「&>を/ dev/null」を追加しました。サブプロセス呼び出しにstderr = PIPEを追加すると、それはなくなりました。私はちょうど場面の裏側のコードを静かにチェックしようとしていました。

誰かがなぜ "&/dev/null"をPythonのサブプロセス呼び出しに追加すると、それが予期せぬ動作をする理由を説明できれば、答えとして選択することができます!

+1

私たちはシェルとしてbashを使っていますが、Pythonは 'sh 'を使って'&> 'をbashとは違って解釈します。 –

関連する問題