Есть ли эквивалент Python для команды "which"

Другими словами, существует ли кросс-платформенный способ узнать, какой файл будет выполняться с помощью subprocess.Popen(file) без его первого запуска?

Ответ 1

Я считаю, что в библиотеках python их нет.

>>> def which(pgm):
    path=os.getenv('PATH')
    for p in path.split(os.path.pathsep):
        p=os.path.join(p,pgm)
        if os.path.exists(p) and os.access(p,os.X_OK):
            return p


>>> os.which=which
>>> os.which('ls.exe')
'C:\\GNUwin32\\bin\\ls.exe'

Ответ 2

Python 3.3 добавил shutil.which(), чтобы обеспечить кросс-платформенное средство для обнаружения исполняемых файлов:

http://docs.python.org/3.3/library/shutil.html#shutil.which

Верните путь к исполняемому файлу, который будет запущен, если был вызван данный cmd. Если не будет вызываться cmd, верните None.

Примеры вызовов:

>>> shutil.which("python")
'/usr/local/bin/python'

>>> shutil.which("python")
'C:\\Python33\\python.EXE'

К сожалению, это не было обращено на 2.7.x.

Ответ 3

Опция для Python 2 и 3:

from distutils.spawn import find_executable

find_executable('python')  # '/usr/bin/python'

find_executable('does_not_exist')  # None

find_executable(executable, path=None) просто пытается найти "исполняемый файл" в каталогах, перечисленных в "пути". По умолчанию os.environ['PATH'], если "путь" равен None. Возвращает полный путь к "исполняемому" или None, если не найден.

Имейте в виду, что в отличие от which, find_executable фактически не проверяет, что результат отмечен как исполняемый. Вы можете вызвать os.access(path, os.X_OK), чтобы проверить это самостоятельно, если хотите убедиться, что subprocess.Popen сможет выполнить файл.


Также следует отметить, что shutil.which для Python 3.3+ был включен и доступен для Python 2.6, 2.7 и 3.x через сторонний модуль whichcraft.

Он доступен для установки через вышеупомянутую страницу GitHub (т.е. pip install git+https://github.com/pydanny/whichcraft.git) или индекс пакета Python (т.е. pip install whichcraft). Его можно использовать так:

from whichcraft import which

which('wget')  # '/usr/bin/wget'