gooderp18绿色标准版
Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

150 Zeilen
6.6KB

  1. #!/usr/bin/env python
  2. """ Which - locate a command
  3. * adapted from Brian Curtin's http://bugs.python.org/file15381/shutil_which.patch
  4. * see http://bugs.python.org/issue444582
  5. * uses ``PATHEXT`` on Windows
  6. * searches current directory before ``PATH`` on Windows,
  7. but not before an explicitly passed path
  8. * accepts both string or iterable for an explicitly passed path, or pathext
  9. * accepts an explicitly passed empty path, or pathext (either '' or [])
  10. * does not search ``PATH`` for files that have a path specified in their name already
  11. * moved defpath and defpathext lists initialization to module level,
  12. instead of initializing them on each function call
  13. * changed interface: which_files() returns generator, which() returns first match,
  14. or raises IOError(errno.ENOENT)
  15. .. function:: which_files(file [, mode=os.F_OK | os.X_OK[, path=None[, pathext=None]]])
  16. Return a generator which yields full paths in which the *file* name exists
  17. in a directory that is part of the file name, or on *path*,
  18. and has the given *mode*.
  19. By default, *mode* matches an inclusive OR of os.F_OK and os.X_OK - an
  20. existing executable file.
  21. The *path* is, by default, the ``PATH`` variable on the platform,
  22. or the string/iterable passed in as *path*.
  23. In the event that a ``PATH`` variable is not found, :const:`os.defpath` is used.
  24. On Windows, a current directory is searched before using the ``PATH`` variable,
  25. but not before an explicitly passed *path*.
  26. The *pathext* is only used on Windows to match files with given extensions appended as well.
  27. It defaults to the ``PATHEXT`` variable, or the string/iterable passed in as *pathext*.
  28. In the event that a ``PATHEXT`` variable is not found,
  29. default value for Windows XP/Vista is used.
  30. The command is always searched without extension first,
  31. even when *pathext* is explicitly passed.
  32. .. function:: which(file [, mode=os.F_OK | os.X_OK[, path=None[, pathext=None]]])
  33. Return first match generated by which_files(file, mode, path, pathext),
  34. or raise IOError(errno.ENOENT).
  35. """
  36. __docformat__ = 'restructuredtext en'
  37. __all__ = 'which which_files pathsep defpath defpathext F_OK R_OK W_OK X_OK'.split()
  38. import sys
  39. from os import access, defpath, pathsep, environ, F_OK, R_OK, W_OK, X_OK
  40. from os.path import exists, dirname, split, join
  41. ENOENT = 2
  42. windows = sys.platform.startswith('win')
  43. defpath = environ.get('PATH', defpath).split(pathsep)
  44. if windows:
  45. defpath.insert(0, '.') # can insert without checking, when duplicates are removed
  46. # given the quite usual mess in PATH on Windows, let's rather remove duplicates
  47. seen = set()
  48. defpath = [dir for dir in defpath if dir.lower() not in seen and not seen.add(dir.lower())]
  49. del seen
  50. defpathext = [''] + environ.get('PATHEXT',
  51. '.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC').lower().split(pathsep)
  52. else:
  53. defpathext = ['']
  54. def which_files(file, mode=F_OK | X_OK, path=None, pathext=None):
  55. """ Locate a file in a path supplied as a part of the file name,
  56. or the user's path, or a supplied path.
  57. The function yields full paths (not necessarily absolute paths),
  58. in which the given file name matches an existing file in a directory on the path.
  59. >>> def test_which(expected, *args, **argd):
  60. ... result = list(which_files(*args, **argd))
  61. ... assert result == expected, 'which_files: %s != %s' % (result, expected)
  62. ...
  63. ... try:
  64. ... result = [ which(*args, **argd) ]
  65. ... except IOError:
  66. ... result = []
  67. ... assert result[:1] == expected[:1], 'which: %s != %s' % (result[:1], expected[:1])
  68. >>> if windows: cmd = environ['COMSPEC']
  69. >>> if windows: test_which([cmd], 'cmd')
  70. >>> if windows: test_which([cmd], 'cmd.exe')
  71. >>> if windows: test_which([cmd], 'cmd', path=dirname(cmd))
  72. >>> if windows: test_which([cmd], 'cmd', pathext='.exe')
  73. >>> if windows: test_which([cmd], cmd)
  74. >>> if windows: test_which([cmd], cmd, path='<nonexistent>')
  75. >>> if windows: test_which([cmd], cmd, pathext='<nonexistent>')
  76. >>> if windows: test_which([cmd], cmd[:-4])
  77. >>> if windows: test_which([cmd], cmd[:-4], path='<nonexistent>')
  78. >>> if windows: test_which([], 'cmd', path='<nonexistent>')
  79. >>> if windows: test_which([], 'cmd', pathext='<nonexistent>')
  80. >>> if windows: test_which([], '<nonexistent>/cmd')
  81. >>> if windows: test_which([], cmd[:-4], pathext='<nonexistent>')
  82. >>> if not windows: sh = '/bin/sh'
  83. >>> if not windows: test_which([sh], 'sh')
  84. >>> if not windows: test_which([sh], 'sh', path=dirname(sh))
  85. >>> if not windows: test_which([sh], 'sh', pathext='<nonexistent>')
  86. >>> if not windows: test_which([sh], sh)
  87. >>> if not windows: test_which([sh], sh, path='<nonexistent>')
  88. >>> if not windows: test_which([sh], sh, pathext='<nonexistent>')
  89. >>> if not windows: test_which([], 'sh', mode=W_OK) # not running as root, are you?
  90. >>> if not windows: test_which([], 'sh', path='<nonexistent>')
  91. >>> if not windows: test_which([], '<nonexistent>/sh')
  92. """
  93. filepath, file = split(file)
  94. if filepath:
  95. path = (filepath,)
  96. elif path is None:
  97. path = defpath
  98. elif isinstance(path, str):
  99. path = path.split(pathsep)
  100. if pathext is None:
  101. pathext = defpathext
  102. elif isinstance(pathext, str):
  103. pathext = pathext.split(pathsep)
  104. if not '' in pathext:
  105. pathext.insert(0, '') # always check command without extension, even for custom pathext
  106. for dir in path:
  107. basepath = join(dir, file)
  108. for ext in pathext:
  109. fullpath = basepath + ext
  110. if exists(fullpath) and access(fullpath, mode):
  111. yield fullpath
  112. def which(file, mode=F_OK | X_OK, path=None, pathext=None):
  113. """ Locate a file in a path supplied as a part of the file name,
  114. or the user's path, or a supplied path.
  115. The function returns full path (not necessarily absolute path),
  116. in which the given file name matches an existing file in a directory on the path,
  117. or raises IOError(errno.ENOENT).
  118. >>> # for doctest see which_files()
  119. """
  120. path = next(which_files(file, mode, path, pathext), None)
  121. if path is None:
  122. raise IOError(ENOENT, '%s not found' % (mode & X_OK and 'command' or 'file'), file)
  123. return path
  124. if __name__ == '__main__':
  125. import doctest
  126. doctest.testmod()
上海开阖软件有限公司 沪ICP备12045867号-1