Adam Pisula
Adam Pisula

Reputation: 135

Python - Communicate with subprocess using stdin

Lately I was trying to write a simple python code which was supposed to communicate with another process using stdin. Here's what I tried so far:

File start.py:

import sys
from subprocess import PIPE, Popen

proc = subprocess.Popen(["python3", "receive.py"], stdout=PIPE, stdin=PIPE, stderr=PIPE)

proc.stdin.write(b"foo\n")
proc.stdin.flush()
print(proc.stdout.readline())

File receive.py:

import sys

while True:
    receive = sys.stdin.readline().decode("utf-8")

    if receive == "END":
        break

    else:
        if receive != "":
            sys.stdout.write(receive + "-" + receive)
            sys.stdout.flush()

Unfortunately, when I python3 start.py as a result I get b''. How should I answer to the prompt of another process?

Upvotes: 2

Views: 2017

Answers (1)

falsetru
falsetru

Reputation: 369424

The sub-process ends early. You can check it by printing stderr of the sub-process.

# after proc.stdin.flush()
print(proc.stderr.read())

Error message:

Traceback (most recent call last):
  File "receive.py", line 4, in <module>
    receive = sys.stdin.readline().decode()
AttributeError: 'str' object has no attribute 'decode'

The reason why the sub-process ends early

sys.stdin.readline() returns a string (not a byte string); Trying to call decode against a string cause AttributeError in Python 3.x.

To fix the issue, remove decode(..) call in receive.py:

receive = sys.stdin.readline()  # without decode.

And, to make start.py complete, send END, and close stdin of sub-process; let sub-process finish gracefully.

proc.stdin.write(b"foo\n")
proc.stdin.flush()
print(proc.stdout.readline())
proc.stdin.write(b'END')  # <---
proc.stdin.close()        # <---
# proc.wait()

Upvotes: 1

Related Questions