Problem
Is there a rogram?
By simple, I’m referring to something like the which command, which would be ideal. I don’t want to manually search PATH or try to run it with Popen & al to see if it fails (which is what I’m doing right now, but assume it’s launchmissiles).
Asked by Piotr Lesnicki
Solution #1
You can use distutils.spawn.find executable, which I know is an old question. Since python 2.4, this has been documented, and it has existed since python 1.6.
import distutils.spawn
distutils.spawn.find_executable("notepad.exe")
Shutil is now available in Python 3.3. which().
Answered by Nathan Binkert
Solution #2
The simplest method I can think of is:
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
Edit: Updated code sample to include logic for handling case where provided argument is already a full path to the executable, i.e. “which /bin/ls”. This behaves similarly to the UNIX ‘which’ command.
As a result of the comments, I’ve changed the code to use os.path.isfile() instead of os.path.exists().
Edit: path.strip(‘”‘) appears to be the incorrect action here. Quoted PATH entries do not appear to be encouraged by either Windows or POSIX.
Answered by Jay
Solution #3
Use the Python standard library’s shutil.which() function. There are batteries included!
Answered by Dr. Jan-Philip Gehrcke
Solution #4
import shutil
command = 'ls'
shutil.which(command) is not None
As a one-liner of Jan-Philip Gehrcke Answer:
cmd_exists = lambda x: shutil.which(x) is not None
As a def:
def cmd_exists(cmd):
return shutil.which(cmd) is not None
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’s Answer is a one-liner, which is also available as a 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')
Last but not least, indented as a function:
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
Answered by 5 revs, 3 users 97%
Solution #5
On Windows, just remember to give the file extension. Otherwise, you’ll have to use the PATHEXT environment option to construct a far more sophisticated is exe for Windows. You could simply use FindPath.
However, why are you looking for the executable in the first place? The operating system will do it for you as part of the popen call, and if the executable is not found, an exception will be raised. All you have to do is catch the appropriate OS exception. If exe is not found on Windows, subprocess.Popen(exe, shell=True) will fail quietly.
Including PATHEXT in the above implementation, which (according to 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
Answered by Suraj
Post is based on https://stackoverflow.com/questions/377017/test-if-executable-exists-in-python