2011-12-25 21 views
5

mam następujące wiersze PythoniePython podproces bash: nawiasy klamrowe

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

Niestety, bash całkowicie ignoruje --exclude = * {git, .svn.} * flag.

Zawęziłem problem do nawiasów klamrowych. --exclude = *. git * będzie działał przez popena Pythona, ale w momencie, w którym wprowadzono nawiasy klamrowe, jestem bezradny. Jakieś sugestie?

Uwaga: Próbowałem uruchomić polecenie przy użyciu biblioteki Python , generuje dokładnie to samo wyjście - i dokładnie tę samą ignorowaną flagę --exclude.

Odpowiedz

2

Zgaduję, że może to być ucieczka powłoki?

Najlepiej byłoby zrobić własne rozszczepienie argumentów i całkowicie uniknąć powłoki.

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

NB: Być może trzeba będzie rozwinąć ~, nie jestem pewien.

Lub jeśli bash ma być rozszerzenie szelki następnie można zrobić to w Pythonie:

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

Zarówno to, jak i specyfikacja powłoki bash działają świetnie! – user1115304

3

Po przejechaniu shell = True, pyton przekłada polecenie /bin/sh -c <command> (jak opisano here)./bin/sh najwyraźniej nie obsługuje rozszerzenia nawiasów klamrowych. Można spróbować następujących zamiast:

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

Zarówno to, jak i dzielenie argumentów w celu uniknięcia powłoki działa świetnie! – user1115304

0

trzeba zacytować że ekspresja zachować bash z oceniając go przed bieżącym katalogu roboczym, gdy ogień je wyłączyć. Masz również błąd z wyszukiwanym hasłem, zakładającym, że szukasz "tekstu" (z cytatami). Twoja ucieczka dostaje cytaty do łańcucha w Pythonie, ale musi być zrobione ponownie, aby powłoka je zobaczyła.

tj. ... --exclude='*{.git,.svn}*' \\\"text\\\" ...

0

Z perspektywy Python POPEN, co masz wrotten prace, pod warunkiem, że uchwycić wyjście w zmiennej Pythona:

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

Ja testowałem w terminalu z Bash Jako domyślny poleceń, a to działa dobrze.

Należy zauważyć, że "grep -E" powinien być preferowany zamiast "egrep", który jest teraz przestarzały.

I na pewno wiesz, że \ jest także ucieczką dla Bash, prawda? Mam na myśli "*", a nawiasy klamrowe są pochłaniane przez Bash i dlatego nie są przekazywane grep. Dlatego powinieneś uciec z nich.

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