Using subprocess module to launch a shell shell script that itself forks a process

Gabriel Genellina gagsl-py2 at yahoo.com.ar
Tue Oct 7 21:23:19 EDT 2008


En Tue, 07 Oct 2008 21:43:41 -0300, Samuel A. Falvo II  
<sam.falvo at gmail.com> escribió:

> I have a shell script script.sh that launches a Java process in the
> background using the &-operator, like so:
>
>  #!/bin/bash
>  java ... arguments here ... &
>
> In my Python code, I want to invoke this shell script using the
> Subprocess module.  Here is my code:
>
> def resultFromRunning_(command):
>     """Invokes a shell command, and returns the stdout response.
>
>     Args:
>         command: A string containing the complete shell command to
> run.
>
>     Results:
>         A string containing the output of the command executed.
>
>     Raises:
>         ValueError if a non-zero return code is returned from the
> shell.
>         OSError if command isn't found, inappropriate permissions,
> etc.
>     """
>
>     L = log4py.Logger().get_instance()
>     L.info("Executing: " + command)
>
>     p = subprocess.Popen(
>         command,
>         shell=True,
>         stdin=subprocess.PIPE,
>         stdout=subprocess.PIPE,
>         stderr=subprocess.STDOUT,
>         close_fds=True
>     )
>
>     outputChannel = p.stdout
>     output = outputChannel.read()
>
>     result = p.wait()
>     if result:
>         raise(ShellError(command, result, output))
>
>     L.info("Result = " + str(output))
>     return output
>
> When running the aforementioned code, it kicks off the shell script,
> and, the shell script kicks off the Java process.  However, the Python
> code never returns from outputChannel.read() until I explicitly kill
> the Java process myself via the kill shell command.

Is your shell script doing something else, apart from invoking the java  
process? If not, you could just invoke java directly from Python. Also,  
you set stdin=PIPE - is your java process expecting some input? you're not  
writing anything to stdin.
Anyway, it's better to use the communicate method instead (it uses select  
to read from both stdout and stderr):

p = subprocess.Popen(...)
output = p.communicate()[0]
result = p.returncode
if result: ...

See  
http://docs.python.org/library/subprocess.html#subprocess.Popen.communicate

-- 
Gabriel Genellina




More information about the Python-list mailing list