2011-12-25 17 views
5

Tengo las siguientes líneas de Python:Python subproceso de Bash: llaves

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

Desafortunadamente, golpe del ignora por completo el --exclude = {* git, svn.} * bandera.

He reducido el problema a las llaves. --exclude = *. git * funcionará a través del popen de Python, pero en el momento en que se introducen las llaves, me siento impotente. ¿Alguna sugerencia?

Nota: He intentado ejecutar el comando usando biblioteca de comandos de Python, se produce exactamente el mismo resultado - y exacta la misma bandera --exclude ignorado.

Respuesta

2

Supongo que es posible que se escape el caparazón?

¿Podría ser mejor dividir los argumentos por su propia cuenta y evitar completamente el shell?

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

Nota: Es posible que tenga que ampliar ~, no estoy seguro.

O si se supone que bash se está expandiendo las llaves, entonces podría hacerlo en Python:

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

Tanto esto como especificar el shell bash funcionan muy bien. – user1115304

3

Cuando se pasa shell = True, pitón traduce el comando para /bin/sh -c <command> (como se describe here)./bin/sh aparentemente no admite la expansión de llaves. Puede intentar lo siguiente en su lugar:

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

¡Esto y dividir los argumentos para evitar el shell funcionan muy bien! – user1115304

0

Usted necesidad de citar que la expresión de mantener golpe de evaluarla con respecto a su directorio de trabajo actual cuando el fuego apagado. También tiene un error con su término de búsqueda suponiendo que está buscando "texto" (con las citas). Su escape obtiene las comillas en la cadena de Python, pero debe volver a hacerse para que el shell las vea.

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

0

Desde una perspectiva Python Popen, obras lo que has wrotten, siempre que capture la salida en una variable de Python:

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

he probado en un terminal con el Bash como comando predeterminado Shell, y funciona bien.

Tenga en cuenta que 'grep -E' debe preferirse a 'egrep', que ahora está en desuso.

Y ciertamente sabes que \ también es el personaje de escape para el Bash, ¿no? Quiero decir, '*' y las llaves son consumidas por el Bash, y por lo tanto no se entregan a grep. Por lo tanto, debes escapar de ellos.

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