Issue With subprocess module - pipe.stdin.close()

Hi Pythoneers,

I am currently getting myself familiar with the subprocess module. I ran the following script in the interactive shell using PyCharm on Windows 11 using interpreter Python v3.13.0.

>>> os.chdir(r'C:\Desktop\Temp_Directory')
>>> from subprocess import Popen, PIPE, call
>>> pipe = Popen('python tester.py', stdin = PIPE)
Testing this new file.
Today we continue grinding!
>>> pipe.stdin.write(b'Pokey\n')
6
>>> pipe.stdin.close()

I notice that the first execution of the line:

>>> pipe.stdin.close()

an error is always generated. But if I re-enter it again as is, it runs just fine (an error is no longer generated).

Does anyone have experience with this module and know why it is behaving this way?
Is this a bug or is there something that I am missing here.

By the way, the module tester.py is an existing module located here:

C:\Desktop\Temp_Directory'

Its only contents are:

print('Testing this new file.')
print('Today we continue grinding!')

I would call pipe.terminate() when done, not attempt to close the stdin stream. I wouldn’t use that stream at all in fact, I’d prefer pipe.communicate:

1 Like
>>> os.chdir(r'C:\Desktop\Temp_Directory')
>>> from subprocess import Popen, PIPE, call
>>> pipe = Popen('python tester.py', stdin = PIPE)
Testing this new file.
Today we continue grinding!
>>> pipe.stdin.write(b'Pokey\n')
6
>>> pipe.stdin.close()

That looks fine.

I notice that the first execution of the line:

>>> pipe.stdin.close()

an error is always generated.

Can you show us this error? Personally, I’d expect this to work in a
programme.

Does anyone have experience with this module and know why it is
behaving this way?
Is this a bug or is there something that I am missing here.

I’ve only used it on UNIXlike systems, not Windows. But I would expect
this to work.

What I can imagine happening is if the subprocess exits promptly without
reading any input. At that point the pipe is closed on the receiving end
and (on UNIX at least) an attempt to write to the pipe would raise the
SIGPIPE signal.

In your code, the write to the pipe happens when you close it; the
pipe.stdin.write() call will be buffered in memory and does not go out
until you flush or close (which implies a flush).

So if the subprocess does not read its input and exits, I can see that
causing you trouble.

Please show us the error.

1 Like

Thank you for responding to my query.

Please have a look in the screenshot image that I posted - it’s there. :eyeglasses: :wink:

I’m on email, and don’t see screenshots unless I hoof it over to the web forum. That was eminently text which could have been copy/pasted.

Anyway, I’ve looked. That’s not what I would have expected from either the first error from the first close, and the silence from the second close.

Terminating the process abruptly by sending it a SIGTERM (Linux) or calling TerminateProcess() (Windows) is not a good idea in the general case. Ideally, the process exits by itself when it’s done and the parent process calls pipe.wait() to synchronize and clean up after the child. pipe.terminate() is fine when the child is misbehaving for some reason, as an exceptional situation.

Cameron is right. The process is long, long terminated before you call write on stdin. The pipe is buffered, so it doesn’t happen immediately. It flushes on close, which throws an error. The second call to close actually does nothing what so ever, because the pipe is already closed. Thus, calling close multiple times is safe (docs say this).

Cameron solved your issue:

print('Testing this new file.')
print('Today we continue grinding!')
input()

You have to synchronize your communication between the processes.

1 Like

Thank you for following up.

Yes, what @cameron suggested did the trick.

:clap:

1 Like