Ilya Sandler <ilya.sand...@gmail.com> 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 <rep...@bugs.python.org>
<http://bugs.python.org/issue1736483>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to