I want to use redirection from bash function return values to e.g. grep, and call it from python.
Even though I am using shell=True in subprocess, this does not seem to work.
Example that works in bash:
grep foo <(echo "fooline")
Example that gives the error /bin/sh: 1: Syntax error: "(" unexpected in python 3.7.3, Ubuntu 19.04:
#!/usr/bin/env python3
import subprocess
subprocess.call('grep foo <(echo "fooline")', shell=True)
According to answers like these, redirection should work with shell=True (and it does for redirecting actual files, but not return values).
EDIT: Added shebang and python version.
2 Answers 2
The inconsistency that you observe is due to the fact that shell=True gives you a sh shell, not bash.
The following is valid in bash but not in sh.
grep foo <(echo "fooline")
Example output:
sh-3.2$ grep foo <(echo "fooline")
sh: syntax error near unexpected token `('
If you use a valid sh expression your approach will work. Alternatively you can specify which shell to use with executable='/bin/bash'. You can also use something like:
subprocess.Popen(['/bin/bash', '-c', cmd])
Comments
The error is a shell error, nothing to do with python. sh chokes on the parentheses of python syntax.
/bin/sh: 1: Syntax error: "(" unexpected
Let's add a shebang (reference: Should I put #! (shebang) in Python scripts, and what form should it take?)
And also stop using shell=True and all. Use real pipes and command lines with arguments (note: this has been tested & works on windows using a native grep command, so now this is portable)
#!/usr/bin/env python3
import subprocess
p = subprocess.Popen(['grep','foo'],stdin = subprocess.PIPE)
p.stdin.write(b"fooline\n")
p.stdin.close()
p.wait()
3 Comments
shell=True?
echo "fooline" | grep foo?