在Python中,是否有一种可移植且简单的方法来测试可执行程序是否存在?

我说的简单是指像which命令这样完美的命令。我不想手动搜索PATH或涉及尝试与Popen & al执行它,看看它是否失败(这就是我现在做的,但想象它是launchmissiles)


当前回答

对于python 3.3及更高版本:

import shutil

command = 'ls'
shutil.which(command) is not None

简·菲利普·格尔克(Jan-Philip Gehrcke)的一句话:

cmd_exists = lambda x: shutil.which(x) is not None

作为一个定义:

def cmd_exists(cmd):
    return shutil.which(cmd) is not None

对于python 3.2及更早版本:

my_command = 'ls'
any(
    (
        os.access(os.path.join(path, my_command), os.X_OK) 
        and os.path.isfile(os.path.join(path, my_command)
    )
    for path in os.environ["PATH"].split(os.pathsep)
)

这是Jay的回答中的一行代码,也是一个lambda func:

cmd_exists = lambda x: any((os.access(os.path.join(path, x), os.X_OK) and os.path.isfile(os.path.join(path, x))) for path in os.environ["PATH"].split(os.pathsep))
cmd_exists('ls')

最后,缩进为函数:

def cmd_exists(cmd, path=None):
    """ test if path contains an executable file with name
    """
    if path is None:
        path = os.environ["PATH"].split(os.pathsep)

    for prefix in path:
        filename = os.path.join(prefix, cmd)
        executable = os.access(filename, os.X_OK)
        is_not_directory = os.path.isfile(filename)
        if executable and is_not_directory:
            return True
    return False

其他回答

这看起来很简单,在python2和python3中都可以使用

try: subprocess.check_output('which executable',shell=True)
except: sys.exit('ERROR: executable not found')

我能想到的最简单的方法:

def which(program):
    import os
    def is_exe(fpath):
        return os.path.isfile(fpath) and os.access(fpath, os.X_OK)

    fpath, fname = os.path.split(program)
    if fpath:
        if is_exe(program):
            return program
    else:
        for path in os.environ["PATH"].split(os.pathsep):
            exe_file = os.path.join(path, program)
            if is_exe(exe_file):
                return exe_file

    return None

编辑:更新的代码示例,以包括处理情况的逻辑,其中提供的参数已经是可执行文件的完整路径,即。“这/bin/ls”。这模拟了UNIX 'which'命令的行为。

编辑:更新为每个注释使用os.path.isfile()而不是os.path.exists()。

编辑:path.strip('"')在这里似乎是错误的。Windows和POSIX似乎都不鼓励引用PATH项。

增加了windows支持

def which(program):
    path_ext = [""];
    ext_list = None

    if sys.platform == "win32":
        ext_list = [ext.lower() for ext in os.environ["PATHEXT"].split(";")]

    def is_exe(fpath):
        exe = os.path.isfile(fpath) and os.access(fpath, os.X_OK)
        # search for executable under windows
        if not exe:
            if ext_list:
                for ext in ext_list:
                    exe_path = "%s%s" % (fpath,ext)
                    if os.path.isfile(exe_path) and os.access(exe_path, os.X_OK):
                        path_ext[0] = ext
                        return True
                return False
        return exe

    fpath, fname = os.path.split(program)

    if fpath:
        if is_exe(program):
            return "%s%s" % (program, path_ext[0])
    else:
        for path in os.environ["PATH"].split(os.pathsep):
            path = path.strip('"')
            exe_file = os.path.join(path, program)
            if is_exe(exe_file):
                return "%s%s" % (exe_file, path_ext[0])
    return None

在标准的Python发行版中有一个which.py脚本(例如在Windows的` \PythonXX\Tools\Scripts\which.py `)。

EDIT: which.py依赖于ls,因此它不是跨平台的。

看到操作系统。路径模块提供一些有用的路径名函数。要检查现有文件是否可执行,请使用os。访问(路径,模式),使用操作系统。X_OK模式。

操作系统。X_OK 要包含在access()的模式参数中的值,以确定是否可以执行path。

编辑:建议的which()实现缺少一个线索-使用os.path.join()来构建完整的文件名。