29 r"""Find the full path to commands.    31 which(command, path=None, verbose=0, exts=None)    32     Return the full path to the first match of the given command on the    35 whichall(command, path=None, verbose=0, exts=None)    36     Return a list of full paths to all matches of the given command on    39 whichgen(command, path=None, verbose=0, exts=None)    40     Return a generator which will yield full paths to all matches of the    41     given command on the path.    43 By default the PATH environment variable is searched (as well as, on    44 Windows, the AppPaths key in the registry), but a specific 'path' list    45 to search may be specified as well.  On Windows, the PATHEXT environment    46 variable is applied as appropriate.    48 If "verbose" is true then a tuple of the form    49     (<fullpath>, <matched-where-description>)    50 is returned for each match. The latter element is a textual description    51 of where the match was found. For example:    53     from HKLM\SOFTWARE\...\perl.exe    56 from __future__ 
import unicode_literals
    59     Show the full path of commands.    62         which [<options>...] [<command-name>...]    65         -h, --help      Print this help and exit.    66         -V, --version   Print the version info and exit.    68         -a, --all       Print *all* matching paths.    69         -v, --verbose   Print out how matches were located and    70                         show near misses on stderr.    71         -q, --quiet     Just print out matches. I.e., do not print out    74         -p <altpath>, --path=<altpath>    75                         An alternative path (list of directories) may    76                         be specified for searching.    77         -e <exts>, --exts=<exts>    78                         Specify a list of extensions to consider instead    79                         of the usual list (';'-separate list, Windows    82     Show the full path to the program that would be run for each given    83     command name, if any. Which, like GNU's which, returns the number of    84     failed arguments, or -1 when no <command-name> was given.    86     Near misses include duplicates, non-regular files and (on Un*x)    87     files without executable access.    90 __revision__ = 
"Id: which.py 1448 2007-02-28 19:13:06Z trentm"    91 __version_info__ = (1, 1, 3)
    92 __version__ = 
'.'.
join(map(str, __version_info__))
    93 __all__ = [
"which", 
"whichall", 
"whichgen", 
"WhichError"]
   110 def _getRegisteredExecutable(exeName):
   111     """Windows allow application paths to be registered in the registry."""   113     if sys.platform.startswith(
'win'):
   114         if os.path.splitext(exeName)[1].lower() != 
'.exe':
   118             key = 
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\" +\
   120             value = _winreg.QueryValue(_winreg.HKEY_LOCAL_MACHINE, key)
   121             registered = (value, 
"from HKLM\\"+key)
   122         except _winreg.error:
   124         if registered 
and not os.path.exists(registered[0]):
   128 def _samefile(fname1, fname2):
   129     if sys.platform.startswith(
'win'):
   130         return ( os.path.normpath(os.path.normcase(fname1)) ==\
   131             os.path.normpath(os.path.normcase(fname2)) )
   133         return os.path.samefile(fname1, fname2)
   135 def _cull(potential, matches, verbose=0):
   136     """Cull inappropriate matches. Possible reasons:   137         - a duplicate of a previous match   139         - not executable (non-Windows)   140     If 'potential' is approved it is returned and added to 'matches'.   141     Otherwise, None is returned.   143     for match 
in matches:  
   144         if _samefile(potential[0], match[0]):
   146                 sys.stderr.write(
"duplicate: %s (%s)\n" % potential)
   149         if not stat.S_ISREG(os.stat(potential[0]).st_mode):
   151                 sys.stderr.write(
"not a regular file: %s (%s)\n" % potential)
   152         elif sys.platform != 
"win32" \
   153              and not os.access(potential[0], os.X_OK):
   155                 sys.stderr.write(
"no executable access: %s (%s)\n"\
   158             matches.append(potential)
   164 def whichgen(command, path=None, verbose=0, exts=None):
   165     """Return a generator of full paths to the given command.   167     "command" is a the name of the executable to search for.   168     "path" is an optional alternate path list to search. The default it   169         to use the PATH environment variable.   170     "verbose", if true, will cause a 2-tuple to be returned for each   171         match. The second element is a textual description of where the   173     "exts" optionally allows one to specify a list of extensions to use   174         instead of the standard list for this system. This can   175         effectively be used as an optimization to, for example, avoid   176         stat's of "foo.vbs" when searching for "foo" and you know it is   177         not a VisualBasic script but ".vbs" is on PATHEXT. This option   178         is only supported on Windows.   180     This method returns a generator which yields either full paths to   181     the given command or, if verbose, tuples of the form (<path to   182     command>, <where path found>).   187         path = os.environ.get(
"PATH", 
"").
split(os.pathsep)
   188         if sys.platform.startswith(
"win"):
   189             path.insert(0, os.curdir)  
   194     if sys.platform.startswith(
"win"):
   196             exts = os.environ.get(
"PATHEXT", 
"").
split(os.pathsep)
   200                 if ext.lower() == 
".exe":
   203                 exts = [
'.CMD', 
'.COM', 
'.EXE', 
'.BAT']
   204         elif not isinstance(exts, list):
   205             raise TypeError(
"'exts' argument must be a list or None")
   208             raise WhichError(
"'exts' argument is not supported on "\
   209                              "platform '%s'" % sys.platform)
   214     if os.sep 
in command 
or os.altsep 
and os.altsep 
in command:
   215         if os.path.exists(command):
   216             match = _cull((command, 
"explicit path given"), matches, verbose)
   223         for i 
in range(len(path)):
   226             if sys.platform.startswith(
"win") 
and len(dirName) >= 2\
   227                and dirName[0] == 
'"' and dirName[-1] == 
'"':
   228                 dirName = dirName[1:-1]
   229             for ext 
in [
'']+exts:
   230                 absName = os.path.abspath(
   231                     os.path.normpath(os.path.join(dirName, command+ext)))
   232                 if os.path.isfile(absName):
   234                         fromWhere = 
"from given path element %d" % i
   235                     elif not sys.platform.startswith(
"win"):
   236                         fromWhere = 
"from PATH element %d" % i
   238                         fromWhere = 
"from current directory"   240                         fromWhere = 
"from PATH element %d" % (i-1)
   241                     match = _cull((absName, fromWhere), matches, verbose)
   247         match = _getRegisteredExecutable(command)
   248         if match 
is not None:
   249             match = _cull(match, matches, verbose)
   257 def which(command, path=None, verbose=0, exts=None):
   258     """Return the full path to the first match of the given command on   261     "command" is a the name of the executable to search for.   262     "path" is an optional alternate path list to search. The default it   263         to use the PATH environment variable.   264     "verbose", if true, will cause a 2-tuple to be returned. The second   265         element is a textual description of where the match was found.   266     "exts" optionally allows one to specify a list of extensions to use   267         instead of the standard list for this system. This can   268         effectively be used as an optimization to, for example, avoid   269         stat's of "foo.vbs" when searching for "foo" and you know it is   270         not a VisualBasic script but ".vbs" is on PATHEXT. This option   271         is only supported on Windows.   273     If no match is found for the command, a WhichError is raised.   276         match = next(
whichgen(command, path, verbose, exts))
   277     except StopIteration:
   278         raise WhichError(
"Could not find '%s' on the path." % command)
   282 def whichall(command, path=None, verbose=0, exts=None):
   283     """Return a list of full paths to all matches of the given command   286     "command" is a the name of the executable to search for.   287     "path" is an optional alternate path list to search. The default it   288         to use the PATH environment variable.   289     "verbose", if true, will cause a 2-tuple to be returned for each   290         match. The second element is a textual description of where the   292     "exts" optionally allows one to specify a list of extensions to use   293         instead of the standard list for this system. This can   294         effectively be used as an optimization to, for example, avoid   295         stat's of "foo.vbs" when searching for "foo" and you know it is   296         not a VisualBasic script but ".vbs" is on PATHEXT. This option   297         is only supported on Windows.   299     return list( 
whichgen(command, path, verbose, exts) )
   311         optlist, args = getopt.getopt(argv[1:], 
'haVvqp:e:',
   312             [
'help', 
'all', 
'version', 
'verbose', 
'quiet', 
'path=', 
'exts='])
   313     except getopt.GetoptError 
as msg:
   314         sys.stderr.write(
"which: error: %s. Your invocation was: %s\n"\
   316         sys.stderr.write(
"Try 'which --help'.\n")
   318     for opt, optarg 
in optlist:
   319         if opt 
in (
'-h', 
'--help'):
   322         elif opt 
in (
'-V', 
'--version'):
   323             print(
"which %s" % __version__)
   325         elif opt 
in (
'-a', 
'--all'):
   327         elif opt 
in (
'-v', 
'--verbose'):
   329         elif opt 
in (
'-q', 
'--quiet'):
   331         elif opt 
in (
'-p', 
'--path'):
   333                 altpath = optarg.split(os.pathsep)
   336         elif opt 
in (
'-e', 
'--exts'):
   338                 exts = optarg.split(os.pathsep)
   349         for match 
in whichgen(arg, path=altpath, verbose=verbose, exts=exts):
   351                 print(
"%s (%s)" % match)
   362 if __name__ == 
"__main__":
   363     sys.exit( 
main(sys.argv) )
 def which(command, path=None, verbose=0, exts=None)
 
std::string join(const std::string &base, const std::string &path)
Join two paths, e.g., base path and relative path. 
 
void split(const std::string &path, std::string &head, std::string &tail)
Split path into two parts. 
 
def whichgen(command, path=None, verbose=0, exts=None)
 
def whichall(command, path=None, verbose=0, exts=None)