Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python subprocess with heredocs

I was playing around with Python's subprocess module, trying a few examples but I can't seem to get heredoc statements to work.

Here is the trivial example I was playing with:

import subprocess
a = "A String of Text"
p = subprocess.Popen(["cat", "<<DATA\n" + a + "\nDATA"])

I get the following error when I run the code above:

cat: <<DATA\nA String of Text\nDATA: No such file or directory

Am I doing it wrong? Is this even possible? If so how would I go about doing it?


Update

Just wanted to say that this should never be performed in a real python program because there are better ways of doing this.

like image 710
MitMaro Avatar asked Dec 13 '22 02:12

MitMaro


2 Answers

The shell "heredoc" support is a shell feature. subprocess.Popen does not run your command through the shell by default, so this syntax certainly won't work.

However, since you're using pipes anyway, there isn't any need to use the heredoc support of the shell. Just write your string a to the stdin pipe of the process you just started. This is exactly what the shell would do with the heredoc anyway.

You can do this with Popen.communicate():

p.communicate(a)

The return value of the communicate() function contains the output of the process (in two streams, see the docs).

like image 200
Greg Hewgill Avatar answered Dec 26 '22 05:12

Greg Hewgill


As others have pointed out, you need to run it in a shell. Popen makes this easy with a shell=True argument. I get the following output:

>>> import subprocess
>>> a = "A String of Text"
>>> p = subprocess.Popen("cat <<DATA\n" + a + "\nDATA", shell=True)
>>> A String of Text

>>> p.wait()
0
like image 27
bstpierre Avatar answered Dec 26 '22 04:12

bstpierre