best way of testing a program exists before using it?

Tim Golden tim.golden at viacom-outdoor.co.uk
Mon Sep 11 11:54:17 EDT 2006


[Rob Wolfe]
| Hari Sekhon wrote:
| > I am writing a wrapper to a binary command to run it and then do
| > something with the xml output from it.
| >
| > What is the best way of making sure that the command is 
| installed on the
| > system before I try to execute it, like the python equivalent of the
| > unix command "which"?
| >
| > Otherwise I'd have to do something like:
| >
| > if os.system('which somecommand') != 0:
| >     print "you don't have %s installed" % somecommand
| >     sys.exit(1)
| >
| > I know that isn't portable which is why a python solution would be
| > better (although this will run on unix anyway, but it'd be 
| nice if it
| > ran on windows too).
| 
| IMHO this is pretty portable:
| 
| >>> def is_on_path(fname):
| ...     for p in os.environ['PATH'].split(os.pathsep):
| ...             if os.path.isfile(os.path.join(p, fname)):
| ...                     return True
| ...     return False
| 

Depends on how "fname" is specified: on Win32, the filename 
itself will have one of the PATHEXT extensions, even though you
conventionally don't specify it (and if you're after
portability you certainly won't). On *nix, tho', you almost
certainly won't have the extension.

As it happens I wrote a script similar to yours this morning
which takes account of the PATHEXT, but because of that, it's
obviously win-specific. Maybe it could be made a bit smarter
to account for the possible absence of the env var.

(This is a cut-down version)

<code>
import os, sys

class x_finished (Exception): pass

paths = ["."] + os.environ.get ("PATH", "").split (";")
exts = [e.lower () for e in os.environ.get ("PATHEXT", ".exe").split
(";")]

if __name__ == '__main__':
  if len (sys.argv) > 1:
    search_for = sys.argv[1]
  else:
    search_for = raw_input ("Search for:")
  
  base, ext = os.path.splitext (search_for)
  if ext:
    exts = [ext]
    
  try:
    for path in paths:
      for ext in exts:
        filepath = os.path.join (path, "%s%s" % (base, ext))
        if os.path.isfile (filepath):
          print filepath
          raise x_finished
  except x_finished:
    pass

</code>

TJG

________________________________________________________________________
This e-mail has been scanned for all viruses by Star. The
service is powered by MessageLabs. For more information on a proactive
anti-virus service working around the clock, around the globe, visit:
http://www.star.net.uk
________________________________________________________________________



More information about the Python-list mailing list