在Python中,是否有一种可移植且简单的方法来测试可执行程序是否存在?
我说的简单是指像which命令这样完美的命令。我不想手动搜索PATH或涉及尝试与Popen & al执行它,看看它是否失败(这就是我现在做的,但想象它是launchmissiles)
在Python中,是否有一种可移植且简单的方法来测试可执行程序是否存在?
我说的简单是指像which命令这样完美的命令。我不想手动搜索PATH或涉及尝试与Popen & al执行它,看看它是否失败(这就是我现在做的,但想象它是launchmissiles)
当前回答
我知道这是一个古老的问题,但是您可以使用distutils.spawn.find_executable。从python 2.4开始就有文档记载,从python 1.6开始就存在了。
import distutils.spawn
distutils.spawn.find_executable("notepad.exe")
此外,Python 3.3现在提供了shutil.which()。
其他回答
基于请求原谅比请求许可更容易(而且,重要的是,该命令可以安全运行),我会尝试使用它并捕获错误(在本例中是OSError -我检查了文件不存在和文件不可执行,它们都给出了OSError)。
如果可执行文件有——version或——help标志,这是一个快速的无操作,这是有帮助的。
import subprocess
myexec = "python2.8"
try:
subprocess.call([myexec, '--version']
except OSError:
print "%s not found on path" % myexec
这不是一个通用的解决方案,但对于很多用例来说是最简单的方法——在这些用例中,代码需要寻找一个已知的可执行文件,该文件可以安全运行,或者至少可以安全运行给定的标志。
增加了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
因此,基本上您希望在挂载的文件系统中找到一个文件(不一定只在PATH目录中)并检查它是否可执行。这可以转化为以下计划:
枚举本地挂载的文件系统中的所有文件 用名称模式匹配结果 对于找到的每个文件,检查它是否可执行
我想说,以一种便携式的方式来做这件事将需要大量的计算能力和时间。这真的是你需要的吗?
*nix平台(Linux和OS X)
这似乎对我很管用:
编辑工作在Linux上,感谢Mestreion
def cmd_exists(cmd):
return subprocess.call("type " + cmd, shell=True,
stdout=subprocess.PIPE, stderr=subprocess.PIPE) == 0
我们在这里所做的是使用内置命令类型并检查退出代码。如果没有这样的命令,type将以1退出(或者一个非零的状态码)。
关于stdout和stderr的部分只是为了屏蔽type命令的输出,因为我们只对退出状态代码感兴趣。
使用示例:
>>> cmd_exists("jsmin")
True
>>> cmd_exists("cssmin")
False
>>> cmd_exists("ls")
True
>>> cmd_exists("dir")
False
>>> cmd_exists("node")
True
>>> cmd_exists("steam")
False
对于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