Ilya Sandler <[email protected]> added the comment:
I don't think this is a bug in python (see below for analysis). Furthermore,
os.popen() is deprecated, so I think this issue can be closed.
Here is my understanding of what's happening.
When you execute :
python -c 'import sys, os; sys.stdout.write(os.popen("while :; do echo yes ;
done | echo hello").read())'
popen() forks and then execs() a /bin/sh like this
/bin/sh -c "while :; do echo yes ; done | echo hello"
But exec() (on Linux at least) inherits the signal handling from the pre-exec
process for the signals which were set to SIG_IGN or SIG_DFL (see e.g here:
http://www.gnu.org/software/libc/manual/html_node/Initial-Signal-Actions.html),
so in this case shell will inherit SIG_IGN setting from python for SIGPIPE.
Furthermore, the "sh" manpage explicitly says that shell will wait for all
processes in the pipeline.
So, the sequence of events will be as follows: echo exits, SIGPIPE is delivered
to the shell and is ignored by the shell and so the shell keeps running the
while loop forever, so .read() call never reaches the eof and your script
blocks.
The original "yes|echo" example on MacOsX has likely been caused by the same
sequence of events. (if "yes" inherits signal handling from shell, then
"yes|echo"
would not block when invoked from command line, but would block when invoked
from python)
Installling your own SIGPIPE handler (or resetting SIGPIPE to SIG_DFL as ilgiz
suggested) should work around this issue.
----------
nosy: +isandler
_______________________________________
Python tracker <[email protected]>
<http://bugs.python.org/issue1736483>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe:
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com