2011-12-25 11 views
5

Iは、次のPython線を有する:Pythonのサブプロセス:中括弧

import subprocess 
subprocess.Popen("egrep -r --exclude=*{.git,.svn}* \"text\" ~/directory", stdout=subprocess.PIPE, shell=True).communicate()[0] 

残念ながら、bashは完全--exclude = * {。gitの、の.svn} *フラグを無視します。

私は中括弧に問題を絞り込んだ。 --exclude = *。git *はpythonのpopenを介して動作しますが、中括弧が導入された瞬間、私は無力です。助言がありますか?

注:私はPythonのコマンドライブラリを使用してコマンドを実行しようとしましたが、まったく同じ出力と全く同じ-excludeフラグが生成されます。

答えて

2

私はそれがシェルエスケープかもしれないと思いますか?

独自の引数を分割してシェルを完全に避けるのが最善でしょうか?

import subprocess 
subprocess.Popen(["egrep","-r","--exclude=*{.git,.svn}*","text","~/directory"], stdout=subprocess.PIPE).communicate()[0] 

NB:~を展開する必要があります。わかりません。

やbashはブレースを拡大することになっているならば、あなたはPythonでそれを行うことができます:あなたがシェルを渡すと(hereが説明するように)

excludes = ['.git','.svn'] 
command = ['egrep','-r'] 
for e in excludes: 
    command.append('--exclude=*%s*'%e) 
command += ["text","~/directory"] 
subprocess.Popen(command, stdout=subprocess.PIPE).communicate()[0] 
+0

これとbashシェルを指定するのは素晴らしいです! – user1115304

3

= Trueの場合、Pythonは/bin/sh -c <command>にコマンドを変換します。/bin/shは中括弧展開をサポートしていません。

+0

これとシェルを避けるために引数を分割することは素晴らしいです! – user1115304

0

発火時にbashが現在の作業ディレクトリに対して評価しないように、式を引用する必要があります。また、 "テキスト"(引用符付き)を探していると仮定すると、検索用語にバグがあります。あなたのエスケープは引用符をPython文字列に入れますが、シェルがそれらを参照できるようにするためにはもう一度やり直す必要があります。

I.e. Pythonのpopenの観点から... --exclude='*{.git,.svn}*' \\\"text\\\" ...

0

、あなたはPythonの変数に出力をキャプチャして作品を、wrottenたもの:

import subprocess 
myOutput = subprocess.Popen("egrep -r --exclude=*{.git,.svn}* \"text\" ~/directory", stdout=subprocess.PIPE, shell=True).communicate()[0] 
print "Output: ", myOutput 

私はデフォルトのシェルコマンドとしてバッシュを持つ端末でテストして、それうまくいく。

「grep -E」は 'egrep'よりも優先されるべきであり、現在は廃止予定です。

あなたは確かに、\はBashのエスケープ文字でもありますよね?つまり、 '*'と中括弧はBashによって消費されるため、grepには渡されません。したがって、それらをエスケープする必要があります。

grep -Er --exclude=\*\{.git,.svn\}\* \"text\" ~/directory