En Wed, 08 Oct 2008 15:24:39 -0300, Samuel A. Falvo II <[EMAIL PROTECTED]> escribió:
On Oct 7, 6:23 pm, "Gabriel Genellina" <[EMAIL PROTECTED]> wrote:

you set stdin=PIPE - is your java process expecting some input? you're not writing anything to stdin.

It does not expect input from stdin.  However, this does not affect
any OTHER scripts or commands I run.

But it *does* affect how subprocess handles the child process internally.

Let's remember to look at the objective facts: for shell scripts that
launch child processes of their own, Python hangs.  For all other
types of commands, it works 100% as expected.

Don't conclude too fast... I've tested a variant (using a Perl script as a replacement instead of a Java program), and it worked fine:

<log>
[EMAIL PROTECTED]:~$ cat foo.sh
#!/bin/sh
perl foo.pl&
echo End of foo.sh

[EMAIL PROTECTED]:~$ cat foo.pl
#!/usr/bin/perl

for ($i=5; $i>0; $i--) {
  print "$i seconds remaining...\n";
  sleep(1);
}
print "End of foo.pl\n";

[EMAIL PROTECTED]:~$ cat foo.py
#!/usr/bin/python2.5

import subprocess

command = "./foo.sh"

p = subprocess.Popen(command,
        shell=True,
        stdin=None,
        stdout=subprocess.PIPE,
        stderr=subprocess.STDOUT,
        close_fds=True
)
print "py: before p.communicate"
output = p.communicate()[0]
print "py: after p.communicate"
print "py: returncode=",p.returncode
print "py: read",len(output),"bytes"
print "py: output=", repr(output)
print "py: End of foo.py"


[EMAIL PROTECTED]:~$ ./foo.py
py: before p.communicate
py: after p.communicate
py: returncode= 0
py: read 143 bytes
py: output= 'End of foo.sh\n5 seconds remaining...\n4 seconds remaining...\n3 seconds remaining...\n2 seconds remaining...\n1 seconds remaining...\nEnd of foo.pl\n'
py: End of foo.py
[EMAIL PROTECTED]:~$ uname -a
Linux debian 2.6.18-4-486 #1 Mon Mar 26 16:39:10 UTC 2007 i686 GNU/Linux
[EMAIL PROTECTED]:~$
</log>

This was tested both with python 2.4.4 and 2.5.2
I don't think it's a Python problem, but something related to java and how it handles stdin/stdout. Try with another program.

But, my question now is, WHY is this an issue?  If the launched
process doesn't read from its stdin, why would it block?

Several reasons - the child process might send enough text to stderr to fill its buffer, and if the parent process doesn't read from the other end of the pipe, the child blocks. That's why I suggested to use communicate instead of stdout.read() - it takes care of such cases.

The only thing I can think of is that the JVM's stdout is tied to the
shell script's stdout, because that's the only way it can remain open
upon the termination of the child process.  I suppose, at this point,
the next place to look is in shell script syntax to find out how to
detach the JVM from the script's process group.

Can't you redirect to a file instead?
java foo.jar  >/tmp/foo.log 2>&1 &

--
Gabriel Genellina

--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to