I need to setup environment with the path to a binary. In the shell, I can use which to find the path. Is there an equivalent in python?
This is my code.
cmd = ["which","abc"]
p = subprocess.Popen(cmd, stdout=subprocess.PIPE)
res = p.stdout.readlines()
if len(res) == 0: return False
return True
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
There is distutils.spawn.find_executable().
Method 2
I know this is an older question, but if you happen to be using Python 3.3+ you can use shutil.which(cmd). You can find the documentation here. It has the advantage of being in the standard library.
An example would be like so:
>>> import shutil
>>> shutil.which("bash")
'/usr/bin/bash'
Method 3
There’s not a command to do that, but you can iterate over environ["PATH"] and look if the file exists, which is actually what which does.
import os
def which(file):
for path in os.environ["PATH"].split(os.pathsep):
if os.path.exists(os.path.join(path, file)):
return os.path.join(path, file)
return None
Good luck!
Method 4
You could try something like the following:
import os
import os.path
def which(filename):
"""docstring for which"""
locations = os.environ.get("PATH").split(os.pathsep)
candidates = []
for location in locations:
candidate = os.path.join(location, filename)
if os.path.isfile(candidate):
candidates.append(candidate)
return candidates
Method 5
If you use shell=True, then your command will be run through the system shell, which will automatically find the binary on the path:
p = subprocess.Popen("abc", stdout=subprocess.PIPE, shell=True)
Method 6
This is the equivalent of the which command, which not only checks if the file exists, but also whether it is executable:
import os
def which(file_name):
for path in os.environ["PATH"].split(os.pathsep):
full_path = os.path.join(path, file_name)
if os.path.exists(full_path) and os.access(full_path, os.X_OK):
return full_path
return None
Method 7
Here’s a one-line version of earlier answers:
import os
which = lambda y: next(filter(lambda x: os.path.isfile(x) and os.access(x,os.X_OK),[x+os.path.sep+y for x in os.getenv("PATH").split(os.pathsep)]),None)
used like so:
>>> which("ls")
'/bin/ls'
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0