2

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?

1 Answer 1

1

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()
Sign up to request clarification or add additional context in comments.

6 Comments

He'll also need to rstrip() the receive line if he wants to compare it with END as it will come with an \n at the end.
@zwer, OP didn't send END at all; and I send END (without newline) in the answer.
END should end with an \n in order to be picked up by the sys.stdin.readline() in receive.py in the first place. Just suggesting improvements to your answer instead of writing mine, don't shoot the messenger :)
@zwer, proc.stdin.close() will make sure sys.stdin.readline() in the sub-process to return. I will not bother to length the answer. :) It's already messed with my poor English. Thank you for your feedback anyway. I didn't mean to shoot somebody :P
Unfortunately this didn't work for me. When I run start.py I get error: Traceback (most recent call last): File "start.py", line 12, in <module> proc.stdin.close() # <--- BrokenPipeError: [Errno 32] Broken pipe
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.