Detecting if a program is currently running.

Mike Meyer mwm at mired.org
Mon Dec 27 00:17:52 EST 2004


Brian <ThisIsNotMyReal at ddress.com> writes:

> On a Slackware 9.1 box, I'm trying to detect if mpg123 is currently 
> running/playing a song so that when the song is done, it'll play the next 
> in the list.  The problem is that popen'ing ps doesn't always give a 
> correct return.  My function is below and I added a second check that runs 
> 1 second later which sometimes works, sometimes doesn't.
>
> Here's my function:
>
> def pid_defunct():
>         #1 = defunct processes
>         #2 = show is currently playing
>         #0 = no mpg123 processes found
>         t = os.popen( "ps axc | grep '[mpg123] <defunct>'" ).read()
>         if len(t) > 0:
>                 return 1
>         else:
>                 t = os.popen( "ps axc | grep 'mpg123'" ).read()
>                 if len(t) > 0:
>                         return 2
>                 else:
>                         print "Check 1: mpg123 is dead"
>                         #Check twice, because popen doesn't always return     
> 	    	    	    	   #correct value
>                         time.sleep(1)
>                         t = os.popen( "ps axc | grep 'mpg123'" ).read()
>                         if len(t) > 0:
>                                 print "Check 1 was wrong"
>                                 return 2
>                         else:
>                                 print "Check 2: mpg123 is dead"
>                                 return 0
>
>
> This function is run during each iteration of a loop with a time.sleep(1) 
> executed right before it.  Is there a better way to make this work?

Yeah, but it takes work on both ends. You could wrap your mpg123 in a
shell script like so:

#!/bin/sh
mpg123 "$@" &
echo $! >/tmp/mpg123.pid


Or in python 2.4:

#!/usr/bin/env python
from subprocess import Popen

p = Popen('mpg123')
pidfile = file('/tmp/mpg123.pid', 'w')
pidfile.write("%d" % p.pid)
pidfile.close()

Then have your check program do (again, using the 2.4 subprocess module)

from subprocess import Popen, PIPE

try:
     pidfile = file('/tmp/mpg123.pid')
except IOError:
     print 'mpg123 is dead'
else:
     pid = pidfile.read()
     t = Popen('ps p %s' % pid, shell=True, stdout=PIPE).stdout
     if t.readlines() < 2:
         print 'mpg123 is dead'
         os.remove('/tmp/mpg123.pid')
         return 0
     return 2

Basically, instead of trusting grep to find mpg123, save the pid in a
file and let ps find it (or not) by pid.

     <mike
-- 
Mike Meyer <mwm at mired.org>			http://www.mired.org/home/mwm/
Independent WWW/Perforce/FreeBSD/Unix consultant, email for more information.



More information about the Python-list mailing list