在Python中,是否有一种可移植且简单的方法来测试可执行程序是否存在?
我说的简单是指像which命令这样完美的命令。我不想手动搜索PATH或涉及尝试与Popen & al执行它,看看它是否失败(这就是我现在做的,但想象它是launchmissiles)
在Python中,是否有一种可移植且简单的方法来测试可执行程序是否存在?
我说的简单是指像which命令这样完美的命令。我不想手动搜索PATH或涉及尝试与Popen & al执行它,看看它是否失败(这就是我现在做的,但想象它是launchmissiles)
当前回答
使用Python标准库中的shutil.which()。 电池包括!
其他回答
在标准的Python发行版中有一个which.py脚本(例如在Windows的` \PythonXX\Tools\Scripts\which.py `)。
EDIT: which.py依赖于ls,因此它不是跨平台的。
只要记住在windows上指定文件扩展名即可。否则,你必须使用PATHEXT环境变量为windows编写一个非常复杂的is_exe。您可能只想使用FindPath。
哦,你为什么还要费心搜索可执行文件呢?操作系统将作为popen调用的一部分为你做这件事,如果找不到可执行文件,将引发一个异常。您所需要做的就是为给定的操作系统捕获正确的异常。注意,在Windows上,subprocess。如果没有找到exe, Popen(exe, shell=True)将会静默失败。
将PATHEXT合并到上面的实现中(在Jay的回答中):
def which(program):
def is_exe(fpath):
return os.path.exists(fpath) and os.access(fpath, os.X_OK) and os.path.isfile(fpath)
def ext_candidates(fpath):
yield fpath
for ext in os.environ.get("PATHEXT", "").split(os.pathsep):
yield fpath + ext
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)
for candidate in ext_candidates(exe_file):
if is_exe(candidate):
return candidate
return None
我知道这是一个古老的问题,但是您可以使用distutils.spawn.find_executable。从python 2.4开始就有文档记载,从python 1.6开始就存在了。
import distutils.spawn
distutils.spawn.find_executable("notepad.exe")
此外,Python 3.3现在提供了shutil.which()。
您可以尝试名为“sh”(http://amoffat.github.io/sh/)的外部库。
import sh
print sh.which('ls') # prints '/bin/ls' depending on your setup
print sh.which('xxx') # prints None
我能想到的最简单的方法:
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项。