1

I know this question has been asked few times already, just couldn't see what's wrong with my usage.

Usage#1

proc = subprocess.Popen(['/usr/bin/find', '/path/to/dir', '-type', 'f', '-name', '"*.gradle"', '-exec', 'grep', '"KEYWORD"', '{}', '/dev/null', ';'], stdout=PIPE, stderr=PIPE)
output, error = proc.communicate()
Error: doesn't list any files.

Usage#2

proc = subprocess.Popen(['/usr/bin/find', '/path/to/dir', '-type', 'f', '-name', '"*.gradle"', '-exec', 'grep', '"KEYWORD"', '{}', '/dev/null', '\\;'], stdout=PIPE, stderr=PIPE)
output, error = proc.communicate()
Error: find: -exec: no terminating ";" or "+"

Usage#3

proc = subprocess.Popen(['/usr/bin/find', '/path/to/dir', '-type', 'f', '-name', '"*.gradle"', '-exec', 'grep', '"KEYWORD"', '{}', '/dev/null', '\;'], stdout=PIPE, stderr=PIPE)
output, error = proc.communicate()
Error: find: -exec: no terminating ";" or "+"

I could get the command working with the shell=True option. However, would like to avoid it as a best practice.

Command works fine when run from the shell.

/usr/bin/find /path/to/dir -type f -name "*.gradle" -exec grep "KEYWORD" {} /dev/null \;

Python Version : 2.7.11
OS X 10.11.3

Appreciate any pointers on how to get this working.

10
  • Better to assign your long command to first a variable and then pass it as a parameter to Popen Commented Feb 23, 2017 at 11:56
  • @ChandaKorat - Tried that, but to no avail Commented Feb 23, 2017 at 11:57
  • Exactly what is your command. can u specify as a string? Commented Feb 23, 2017 at 11:59
  • Why is it a 'best practice' to not use the shell keyword argument? Commented Feb 23, 2017 at 12:01
  • @ChandaKorat - Included sample command which runs fine from the shell Commented Feb 23, 2017 at 12:10

2 Answers 2

4

You don't need to use shell escapes when you build a command as list to use with Popen, so in this case \; would be interpreted as a literal backslash followed by a semicolon, while find expect to see only a semicolon as single argument. Also "KEYWORD" will include the quotes and therefore not find KEYWORD without surrounding quotes. Similar for "*.gradle", that will only match for filenames enclosed in quotes.

proc = subprocess.Popen(['/usr/bin/find', '/path/to/dir', '-type', 'f',
                         '-name', '*.gradle', '-exec', 'grep', 'KEYWORD',
                         '{}', '/dev/null', ';'],
                         stdout=PIPE, stderr=PIPE)
Sign up to request clarification or add additional context in comments.

3 Comments

Awesome, thanks! it worked :) Quoting the KEYWORD turned out to be the problem.
Just one hint: adding /dev/null as input file for grep seems unneccessary, it only has the effect of making grep prepend printed lines with the filename, which you can also achieve by usig the -H (--with-filename) flag.
Yes, that looks neat. Thanks!
0

Try this,

cmd='/usr/bin/find /path/to/dir -type f -name "*.gradle" -exec grep "KEYWORD" {} /dev/null \;'
proc = subprocess.Popen(cmd.split(), stdout=PIPE, stderr=PIPE)
output, error = proc.communicate()

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.