How to use only a sub shell to execute many commands in python
Gabriel Genellina
gagsl-py2 at yahoo.com.ar
Fri Jan 18 11:49:23 EST 2008
En Fri, 18 Jan 2008 09:31:25 -0200, raocheng <rc.china at gmail.com> escribi�:
> Please see the following code.
> Suppose I have many shell commands to be executed. And I don't want to
> fork a sub shell for each command(eg: status,output =
> commands.getstatusoutput(cmd)) because it is too expensive. I want to
> use only one sub shell to execute all these commands and want to get
> each command's output. How can I accomplish this task ? Thanks in
> advance.
The hard part is to determine WHEN the command has completed its
execution, because there is no indication of that. One way would be to set
a relatively uncommon prompt, and look for that string in stdout. You
can't read beyond that, else the code would block.
Another way is to use a separate thread to read from stdout/stderr, and
set a timeout; when no more output comes whithin the timeout, you assume
the command has finished.
The code below uses the first approach, changing the prompt to <$$$>\r\n.
I've tested it on Windows only, but should work on Linux too with some
minor modifications.
import subprocess
from os import getenv
# Windows only, this is to determine the shell in use
# Linux users may try with getenv("SHELL", "sh")
shell = getenv("COMSPEC", "cmd")
p = subprocess.Popen(shell, stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
expected = '<$$$>\r\n'
cmds = ['prompt $L$$$$$$$G$_','date /t','cd','dir','ipconfig /all']
# The first command above sets an uncommon prompt, ending with a newline.
# On Linux use PS1=whatever, but make sure it ends in \n and set the
# expected variable accordingly.
for cmd in cmds:
print ">>>",cmd
p.stdin.write('%s\n' % cmd)
while True:
line = p.stdout.readline()
if line.endswith(expected): break
print line,
print "Waiting for subshell to terminate"
p.stdin.write("exit\n")
p.wait()
print "Done"
--
Gabriel Genellina
More information about the Python-list
mailing list