Are Python.Popen () subprocess results different from command line?

Using Cygwin on Windows 7 x32, the find gives the correct results in the VS solutions directory:

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

but the same command with Python subprocess.Popen() seems to match only with * :

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

What happened to my call to Popen() ?

+1
source share
3 answers

The following works for me:

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

Note the removal of double quotes around *.sln and setting the shell to False .

This ensures that *.sln is passed to find verbatim and is not extended by the shell.

edit: The following also works:

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

On POSIX systems, when you use Popen(['find', '.', '-iname', '"*.sln"'], shell=True) , Python does this:

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

If you read the documentation for sh , you will find that only the first argument after -c treated as a command line that should be executed as a shell script. The remaining arguments are actually considered shell script arguments. In this case, since the shell of the script consists solely of the name of the find command, the arguments are ignored. This can be observed if you run:

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

The code should be:

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

All Articles