Shani Shalgi
Shani Shalgi

Reputation: 705

Using stdin instead of a file in a python call to a perl script

I'm running a perl script that accepts a file as input from Python using subprocess.Popen(). I now need the input to the script to accept input from the standard input and not a file. If I run the perl scrip from the shell like this:

perl thescript.perl --in /dev/stdin --other_args other_values 

It works perfectly. However, in python, nothing happens using the following commands:

mytext = "hi there"
args = ["perl", "myscript.perl", "--in", "/dev/stdin", "--other_args", other_values]
pipe = subprocess.Popen(args, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
result = pipe.communicate(input=mytext.encode("utf8"))[0]`

result always returns empty (I've also tried using pipe.stdin.write(mytext") and result=pipe.stdout.read())

Please let me know what I'm doing wrong.

Upvotes: 2

Views: 812

Answers (2)

Shani Shalgi
Shani Shalgi

Reputation: 705

Thanks to the comments by @J.F.Sebastian above, I managed to solve this problem with echo and pipes.

args = ["perl", "myscript.perl", "--in", "/dev/stdin", "other_args", other_vals]
pipe1 = subprocess.Popen(["echo", mytext], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
pipe2 = subprocess.Popen(args, stdin=pipe1.stdout, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
pipe1.stdout.close()
result = pipe2.communicate()[0]

Which returns the expected output. Still not sure why the original (posted in the question) didn't work (using communicate to send the text to the stdin)

Upvotes: 2

jfs
jfs

Reputation: 414079

/dev/stdin should work (if it works in the shell on your system):

>>> from subprocess import Popen, PIPE
>>> import sys
>>> p = Popen([sys.executable, '-c', 'print(open("/dev/stdin").read()[::-1])'],
...           stdin=PIPE, stdout=PIPE)
>>> p.communicate(b'ab')[0]
'ba\n'

stdin=PIPE creates a pipe and connects it to the child process' stdin. Reading from /dev/stdin is equivalent to reading from the standard input (0 fd) and therefore the child reads from the pipe here as shown in the example.

Upvotes: 0

Related Questions