classification
Title: os.popen('yes | echo hello') stuck
Type: behavior Stage: test needed
Components: Library (Lib) Versions: Python 2.6
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: cpegeric, ilgiz (2)
Priority: Keywords

Created on 2007-06-13 13:41 by cpegeric, last changed 2009-03-31 01:19 by ajaksu2.

Messages (8)
msg32314 - (view) Author: Eric (cpegeric) Date: 2007-06-13 13:41
after calling os.popen('yes | echo hello'), the process never returns.
msg32315 - (view) Author: Ilguiz Latypov (ilgiz) Date: 2007-06-13 17:07

Could you try the same command from your shell?

I am guessing "yes" will write an error message about the broken pipe to stderr.

$ python -c 'import sys, os; sys.stdout.write(os.popen("yes | echo hello").read())'
yes: standard output: Broken pipe
yes: write error
hello

$ python -c 'import sys, os; sys.stdout.write(os.popen3("yes | echo hello")[1].read())'
hello
msg32316 - (view) Author: Eric (cpegeric) Date: 2007-06-14 01:28
command line also get stuck.  The OS is MacOSX.  Python version 2.3.5.  Will it help update to new version?

I quited the program by Ctrl-C.

 python -c 'import sys, os; sys.stdout.write(os.popen("yes | echo hello").read())'
^CTraceback (most recent call last):
  File "<string>", line 1, in ?
KeyboardInterrupt



% python -c 'import sys, os; sys.stdout.write(os.popen3("yes | echo hello")[1].read())'
^CTraceback (most recent call last):
  File "<string>", line 1, in ?
KeyboardInterrupt

msg32317 - (view) Author: Ilguiz Latypov (ilgiz) Date: 2007-06-14 02:24
I've realized my suggestion was not precise.  I meant asking to run the argument to popen() rather than popen().

That is, I would run this from command line to see if there is an issue with the shell:

$ yes | echo hello

msg32318 - (view) Author: Eric (cpegeric) Date: 2007-06-14 02:46
sorry for the misunderstanding.

Here is the result. 

% yes | echo hello
hello
% echo $?
0
%
msg32319 - (view) Author: Ilguiz Latypov (ilgiz) Date: 2007-06-14 03:15

It appears your "yes" does not catch SIGPIPE.  I've reproduced the issue with

$ python -c 'import sys, os; sys.stdout.write(os.popen("while :; do echo yes ; done | echo hello").read())'
Traceback (most recent call last):
  File "<string>", line 1, in <module>
KeyboardInterrupt

The documentation on Python module signal says SIGPIPE is ignored by Python as well.  My work-around to this was to catch SIGPIPE, but the GNU C library would terminate the whole script.

$ python -c 'import sys, os, signal; signal.signal(signal.SIGPIPE, signal.SIG_DFL); sys.stdout.write(os.popen("while :; do echo yes ; done | echo hello").read())'
hello

http://www.gnu.org/software/libc/manual/html_node/Operation-Error-Signals.html

Perhaps, writing own signal handler might help.
msg32320 - (view) Author: Ilguiz Latypov (ilgiz) Date: 2007-06-14 03:22
The SIG_DFL default handler seems to terminate the current process (argument to popen()), not Python script.
msg32321 - (view) Author: Eric (cpegeric) Date: 2007-06-14 03:49
It works now. thank you.
History
Date User Action Args
2009-03-31 01:19:34ajaksu2setpriority: normal ->
stage: test needed
type: behavior
versions: + Python 2.6, - Python 2.3
2007-06-13 13:41:20cpegericcreate