¿Los resultados de Subprocess.Popen () de Python difieren de la línea de comandos?

Al usar Cygwin en Windows 7 x32, en un directorio de soluciones VS, el comando de find produce resultados correctos:

 $ find . -iname "*.sln" ./ProjName.sln 

pero el mismo comando con el subprocess.Popen() Python parece coincidir con * solo:

 >>> import subprocess >>> print subprocess.Popen(['find', '.', '-iname', '"*.sln"'], ... stdout=subprocess.PIPE, shell=True).communicate()[0] . ./.git ./.git/COMMIT_EDITMSG ./.git/config ./.git/description  

¿Qué pasa con mi llamada de Popen() ?

Los siguientes trabajos para mí:

 >>> import subprocess >>> print subprocess.Popen(['find', '.', '-iname', '*.sln'], ... stdout=subprocess.PIPE, shell=False).communicate()[0] 

Tenga en cuenta la eliminación de comillas dobles alrededor de *.sln y la configuración de shell en False .

Esto asegura que el *.sln se pasa para find textualmente y no es expandido por el shell.

Edición: Lo siguiente también funciona:

 >>> print subprocess.Popen(['find . -iname "*.sln"'], ... stdout=subprocess.PIPE, shell=True).communicate()[0] 

En los sistemas POSIX, cuando usa Popen(['find', '.', '-iname', '"*.sln"'], shell=True) , Python hace esto:

 /bin/sh -c find . -iname "*.sln" 

Si lees la documentación de sh , encontrarás que solo el primer argumento después de -c se trata como una cadena de comandos que se ejecutará como un script de shell. Los argumentos restantes en realidad se tratan como argumentos al script de shell . En este caso, como la secuencia de comandos de shell consiste únicamente en el nombre de comando “buscar”, los argumentos se ignoran. Puedes observar este comportamiento si corres:

 >>> subprocess.call(['echo arg0 = $0, arg1 = $1', 'foo', 'bar'], shell=True) arg0 = foo, arg1 = bar 0 

El código debe ser:

 print subprocess.Popen(['find . -iname "*.sln"'], stdout=subprocess.PIPE, shell=True).communicate()[0]