[ python-Bugs-1194328 ] Reading from a killed shell script with popen* under linux

SourceForge.net noreply at sourceforge.net
Tue May 3 11:49:51 CEST 2005


Bugs item #1194328, was opened at 2005-05-03 09:44
Message generated for change (Comment added) made by boukthor
You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&atid=105470&aid=1194328&group_id=5470

Category: Python Library
Group: Platform-specific
Status: Open
Resolution: None
Priority: 5
Submitted By: Vinz (boukthor)
Assigned to: Nobody/Anonymous (nobody)
Summary: Reading from a killed shell script with popen* under linux

Initial Comment:
These are problems I've run into under linux (Mandrake
10.0 through 2006.0, Debian 3.1 and Gentoo) with python
versions ranging from 2.3.3 to 2.4:

If you run this:

import os
pout = os.popen("/bin/sleep 999")
print pout.read()
print pout.close()

and kill the "sleep", you get the desired behaviour:
the read returns an empty string when the process gets
killed and the close returns the killing signal.
However, if you put the "sleep" command in a shell
script, for example this simple "/tmp/test.sh":

#!/bin/sh
sleep 999

and run the script through popen (or one of the popen*
method of the os and popen2 module)

import os
pout = os.popen("/tmp/test.sh")
print pout.read()
print pout.close()

then kill the sh running "test.sh", the read never
returns and the shell remains as a zombie. You can get
some strange behaviour with the Popen* classes too
(whether bypassing the shell intervention or not). For
example, run this (and kill the subshell):

import popen2
sub = popen2.Popen3("/tmp/test.sh")
print sub.wait()
print sub.fromchild.read()

this time the wait correctly returns the signal that
killed the shell and removes it from the process table,
but the read hangs again.

As an added oddity, if you run the popen command from
an interactive prompt and raise a KeyboardInterrupt by
pressing Ctrl-C before trying to read from the pipe,
you kill the subprocess with the SIGINT...



I have a final suggestion: if you try reading the
output of a popen* method with a "for" statement like this:

import os
pout = os.popen("for i in $(seq 1 10); do echo $i;
sleep 1; done")
for l in pout: print l,

it waits for the subprocess to complete before going
into the loop. To get the output as it is piped, you
have to use the poll method of the Popen* classes
(which is not available under OSes other than Unix):

sub = popen2.Popen3("for i in $(seq 1 10); do echo $i;
sleep 1; done")
while (-1 == sub.poll()): print sub.fromchild.readline()

I don't know if this last behaviour can be fixed or not
but I'd suggest some mention of this in the manual if
it can't.

----------------------------------------------------------------------

>Comment By: Vinz (boukthor)
Date: 2005-05-03 09:49

Message:
Logged In: YES 
user_id=638508

Oops, just saw the report #1180160. I missed it because I
searched for popen, not Popen before posting. My bad. I'll
cross-reference the two.

----------------------------------------------------------------------

You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&atid=105470&aid=1194328&group_id=5470


More information about the Python-bugs-list mailing list