2012-01-23 9 views
4

私はpopenのは、実行したい:Pythonのpopenのgrepが

シェルから実行
grep -i --line-buffered "grave" data/*.txt 

、これは私の希望の結果が得られます。私は、私はgrepをテストする非常に同じディレクトリに、PythonのREPLを起動し、the instruction from the docsに従うなら、私はpopenのを養うために、適切な引数リストがどうあるべきか得る:

['grep', '-i', '--line-buffered', 'grave', 'data/*.txt'] 

p = subprocess.Popen(args)の結果は

です
grep: data/*.txt: No such file or directory 

と私はp = subprocess.Popen(args, shell=True)をしようとすると、私が手:

Usage: grep [OPTION]... PATTERN [FILE]... 
Try `grep --help' for more information. 

指名手配のプロセスを実行する方法上の任意のヘルプ?私はMacOS Lionにいる。

答えて

7

*をbashに入力すると、シェルはコマンドを実行する前に、指定されたディレクトリのファイルに展開します。 PythonのPopenはそのようなことはしません。Popenを呼び出すと、dataディレクトリにある.txtすべてのファイルではなく、dataディレクトリに*.txtというファイルがあります。そのファイルは存在せず、予想されるエラーが発生します。

はpopenのに shell=Trueを渡すことで、あなたがシェルを介してコマンドを実行するためのpythonを伝えることができ、これを解決するには、次に翻訳さ

subprocess.Popen('grep -i --line-buffered grave data/*.txt', shell=True) 

subprocess.Popen(['/bin/sh', '-c', 'grep -i --line-buffered "grave" data/*.txt']) 

としてはthe documentation of Popenで説明しました。

/bin/sh -c "grep -i --line-buffered "grave" data/*.txt"(N.B.コマンドを引用符で囲み、shの1つの引数にする)を実行したいので、ここではリストの代わりに文字列を使用する必要があります。リストを使用すると、このコマンドが実行されます:/bin/sh -c grep -i --line-buffered "grave" data/*.txt、これは単にgrepを実行して出力します。 。データ/ * TXTあなたがglobモジュールを使用することにより、例えば、youselfそれを実行する必要があります

4

問題は、シェルがファイルグロブあなたのためになるということです。

import glob 
cmd_line = ['grep', '-i', '--line-buffered', 'grave'] + glob.glob('data/*.txt') 
+0

+1プラットフォーム非依存 –

+0

ありがとう。プラットフォームの独立性を高めるためには、 'data/\ *。txt'の代わりにos.path.join( 'data'、 '\ *。txt' –

関連する問題