Reputation: 1587
Using Cygwin on Windows 7 x32, in a VS solution directory, the find
command produces correct results:
$ find . -iname "*.sln"
./ProjName.sln
but the same command with Python's subprocess.Popen()
seems to be matching on *
alone:
>>> 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's wrong with myPopen()
call?
Upvotes: 1
Views: 1630
Reputation: 17960
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'll find that only the first argument after -c
is treated as a command string to be executed as a shell script. The remaining arguments are actually treated as arguments to the shell script. In this case, as the shell script consists solely of the command-name "find", the arguments are ignored. You can observe this behaviour if you run:
>>> subprocess.call(['echo arg0 = $0, arg1 = $1', 'foo', 'bar'], shell=True)
arg0 = foo, arg1 = bar
0
Upvotes: 2
Reputation: 500913
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 the setting of shell
to False
.
This makes sure that the *.sln
is passed to find
verbatim and is not expanded by the shell.
edit: The following also works:
>>> print subprocess.Popen(['find . -iname "*.sln"'],
... stdout=subprocess.PIPE, shell=True).communicate()[0]
Upvotes: 3
Reputation: 8288
The code should be:
print subprocess.Popen(['find . -iname "*.sln"'], stdout=subprocess.PIPE, shell=True).communicate()[0]
Upvotes: 0