Is There a Python Equivalent to the ‘which’ Command?
Is there a cross-platform way in Python to determine which file will be executed by subprocess.Popen(file)
without actually executing it? In other words, is there a Python equivalent to the Unix which
command?
I’ve worked with Python for years, and for anyone needing a Python alternative to the Unix which
command, here’s a straightforward approach. Python 3.3 introduced shutil.which()
—a built-in, easy-to-use solution that directly mimics the Unix command. It’s reliable and simple:
import shutil
file = 'python'
file_path = shutil.which(file)
if file_path:
print(f"The executable for '{file}' is located at: {file_path}")
else:
print(f"'{file}' not found.")
This works like a charm to locate the path of the executable. So if you’re ever wondering ‘which python’ executable you’re running, this is your go-to method.
@ian-partridge’s method is great, especially for Python 3.3+. But let me add something interesting here for those who like a bit more manual control. If you want to simulate the which
functionality without relying on shutil
, you can use os.environ
and iterate through the system’s PATH
. This gives you more insight into how it works under the hood. Here’s a snippet:
import os
def which(file):
path_dirs = os.environ["PATH"].split(os.pathsep)
for directory in path_dirs:
executable = os.path.join(directory, file)
if os.path.isfile(executable) and os.access(executable, os.X_OK):
return executable
return None
file = 'python'
file_path = which(file)
if file_path:
print(f"The executable for '{file}' is located at: {file_path}")
else:
print(f"'{file}' not found.")
This method works for any version of Python, so whether you’re troubleshooting or just exploring ‘which python’ is being used, it’s a versatile choice!
I like how @shashank_watak gave us the manual route—really useful for learning the internals! But let’s not forget the power of leveraging existing Unix tools when working on Unix-based systems. If you prefer to directly invoke the which
command itself from Python, the subprocess
module has you covered. Here’s how you can do it:
import subprocess
def which(file):
try:
result = subprocess.run(['which', file], capture_output=True, text=True, check=True)
return result.stdout.strip()
except subprocess.CalledProcessError:
return None
file = 'python'
file_path = which(file)
if file_path:
print(f"The executable for '{file}' is located at: {file_path}")
else:
print(f"'{file}' not found.")
This approach essentially combines the best of both worlds—using the Pythonic way to call the native which
command. If you ever find yourself asking ‘which python’ executable your system is picking up, this method is efficient and directly aligns with Unix practices.