Python中是否有类似于'which'命令的等价物?

40

换句话说,是否有一种跨平台的方法可以在不执行文件的情况下知道 subprocess.Popen(file) 将要执行哪个文件?


2
https://github.com/amoffat/pbs/blob/master/pbs.py#L95 - Josh Lee
默认情况下,子进程继承父进程的环境。因此,对于PATH中的任何可执行文件(或操作系统相应的等效文件),您无需指定位置。 - Roland Smith
@JoshLee 看起来 PBS 不再可用。 - Joe
2
https://github.com/amoffat/sh/blob/master/sh.py#L162 - Josh Lee
3个回答

86

Python 3.3新增了shutil.which()函数,可以跨平台查找可执行文件:

http://docs.python.org/3.3/library/shutil.html#shutil.which

返回执行给定命令时将运行的可执行文件路径。如果没有命令将被调用,则返回None。

示例调用:

>>> shutil.which("python")
'/usr/local/bin/python'

>>> shutil.which("python")
'C:\\Python33\\python.EXE'

不幸的是,这个功能没有被回溯到2.7.x版本。


4
Python3.3 版本中 shutil.which 的源代码在这里(仅有几十行):http://hg.python.org/cpython/file/6860263c05b3/Lib/shutil.py#l1068 - joemaller
2
如果你将第1110行改为if any([cmd.lower().endswith(ext.lower()) for ext in pathext])(将生成器转换为列表),那么它就可以在Python 2.7中运行了。 - Chris Hagmann
4
可在此处找到回溯版本:https://github.com/mbr/shutilwhich - nu everest
shutil.which 也非常慢 - Travis Bear
3
2021年这应该是被接受的答案。 - cjauvin

15

Python 2和3的选择:

from distutils.spawn import find_executable

find_executable('python')  # '/usr/bin/python'

find_executable('does_not_exist')  # None

find_executable(executable, path=None)函数的作用是在“path”所列出的目录中查找名为“executable”的可执行文件。如果“path”参数未提供,则默认使用os.environ['PATH']。函数返回名为“executable”的完整路径,如果没有找到则返回None

需要注意的是,与which不同,find_executable并未检查结果是否标记为可执行文件。如果您想确保subprocess.Popen能够执行该文件,可以调用os.access(path, os.X_OK)进行检查。


另外值得一提的是,Python 3.3+ 的shutil.which已经被移植并且通过第三方模块whichcraft(可用于 Python 2.6、2.7 和 3.x)进行了支持。

你可以通过上述 GitHub 页面(即pip install git+https://github.com/pydanny/whichcraft.git)或者 Python 包索引(即pip install whichcraft)进行安装。它的使用方法如下:

from whichcraft import which

which('wget')  # '/usr/bin/wget'

1
避免使用distutils,因为它使用了已弃用的imp,会产生运行时警告。 - sorin

10

过时的(不再正确)

我相信Python库中没有这样的东西。

>>> def which(pgm):
    path=os.getenv('PATH')
    for p in path.split(os.path.pathsep):
        p=os.path.join(p,pgm)
        if os.path.exists(p) and os.access(p,os.X_OK):
            return p

        
>>> os.which=which
>>> os.which('ls.exe')
'C:\\GNUwin32\\bin\\ls.exe'

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接