[Tutor] os.system

Michael P. Reilly arcege@speakeasy.net
Mon, 19 Nov 2001 18:12:53 -0500


On Mon, Nov 19, 2001 at 10:26:29PM +0100, Hans Gubitz wrote:
> Thank you for the hints. What do you think about:
> 
> 
> import os, string
> class bild:
>     def __init__(self, host, bild):
>         self.host = host
>         self.bild = bild
>         kommando = "xv -display %s:0.0 %s&" % (host,bild)
>         os.system(kommando)
>         self.pid = self.suche()
>     def suche(self):
>         pr = os.popen("ps axw","r")
>         zeilen=pr.readlines()
>         print zeilen
>         pr.close()
>         for zeile in zeilen:
>             if string.find(zeile,self.host) >= 0 and string.find(zeile,self.bild) >= 0:
>                 pid = string.split(zeile," ")[0]
>         return int(pid)
>     def kill(self):
>         os.kill(self.pid,15)

You might want to look at the popen2.Popen3 object.  The problem with
your mechanism is that

* not all UNIX systems use "ps axw" for what you wish, and
* if another process of your program, or the same process, calls
  bild() with the same arguments, or if someone calls the same resulting
  command to 'xv', then you could possibly get the wrong pid.

The Popen3 object will give you the pid, and the file objects to and from
the process.  There is a poll() method for you to periodically check to
see if the process had finished - this is probably more of what you want.

class bild:
  def __init__(self, host, bild)
    self.host = host
    self.bild = bild
    cmd = 'xv -display %s:0.0 %s' % (host, bild)
    self.pid = popen2.Popen3(cmd, 0)

  def kill(self):
    sts = self.pid.poll()
    if sts == -1:
      os.kill(self.pid.pid, 15)
      sts = self.pid.wait()  # need this to prevent zombies at least
    return sts

This might be a little more secure for your needs.

  -Arcege

-- 
+----------------------------------+-----------------------------------+
| Michael P. Reilly                | arcege@speakeasy.net              |