running and managing background shell commands

Donn Cave donn at u.washington.edu
Wed Dec 15 14:51:44 EST 1999


Quoth Dimitri Papadopoulos <papadopo at shfj.cea.fr>:
| I am translating this shell function to Python:
|
| 	_new_browser() {
| 		# start Netscape in the background
| 		# this will always return 0, even in the face of a failure...
| 		netscape "$*" &
| 		# ... so wait a few seconds, and check that Netscape is still alive
| 		i=3
| 		while [ $i -gt 0 ]
| 		do
| 			sleep 1
| 			ps -p $! > /dev/null || return 1
| 			i=`expr $i - 1`
| 		done
| 		return 0
| 	}
|
| How can I rewrite this function? As far as I know:
| 1) commands.getstatus cannot start a background command
| 2) os.system does start a background command
| 3) but $! is not available
| Do I have to fork and then execv - which is probably what the shell does anyway?

You don't have to fork and execv, though for me that would be the more
straightforward way to approach it.

Try something like this -

    fp = os.popen('exec 2>&1 \n netscape & \n echo $!', 'r')
    pidline = fp.readline()
    fp.close()
    if pidline:
        try:
            pid = string.atoi(pidline)
        except ValueError:
            raise browser_error, pidline
    else:
        raise browser_error, 'shell abort'
    i = 0
    while i < timeout:
        try:
             os.kill(pid, 0)
        except os.error:
             raise browser_error, '


The "exec 2>&1" line redirects the diagnostics and errors to the
pipe along with normal output.  I used \n instead of ; because of
a weakness in the shell's grammatical ideas about &.

	Donn Cave, University Computing Services, University of Washington		donn at u.washington.edu



More information about the Python-list mailing list