В Python есть ли портативный и простой способ проверить, существует ли исполняемая программа?
Под простым я подразумеваю что-то вроде which
команды, которая была бы просто идеальной. Я не хочу искать PATH вручную или что-то, связанное с попыткой выполнить его с помощью Popen
& al, и посмотреть, не получится ли это (это то, что я делаю сейчас, но представьте, что это так launchmissiles
)
which
сторонний модуль: code.activestate.com/pypm/whichОтветы:
Самый простой способ, который я могу придумать:
Редактировать : Обновлен пример кода, чтобы включить логику для обработки случая, когда предоставленный аргумент уже является полным путем к исполняемому файлу, т.е. Это имитирует поведение UNIX-команды 'which'.
Изменить : Обновлено для использования os.path.isfile () вместо os.path.exists () для комментариев.
Редактировать :
path.strip('"')
кажется, что здесь не так. Ни Windows, ни POSIX, похоже, не поддерживают цитируемые элементы PATH.источник
PATHEXT
env var, потому чтоcommand
оно так же верно, какcommand.com
иscript
vsscript.bat
Я знаю, что это древний вопрос, но вы можете использовать
distutils.spawn.find_executable
. Это было задокументировано начиная с python 2.4 и существует с python 1.6.Кроме того, Python 3.3 теперь предлагает
shutil.which()
.источник
win32
,distutils.spawn.find_executable
реализация ищет только.exe
вместо того, чтобы использовать список расширений для поиска набора%PATHEXT%
. Это не очень хорошо, но это может работать для всех случаев, которые кому-то нужны.from distutils import spawn
php_path = spawn.find_executable("php")
distutils.spawn
, надежно недоступен: с моей установкой системы (/ usr / bin / python) Python 2.7.6 на OS X 10.10 я получаю:AttributeError: 'module' object has no attribute 'spawn'
хотя странно, что он работает на той же машине с той же версией Python, но из виртуальная установка.import distutils.spawn
следуйтеfrom distutils import spawn
синтаксису или следуйте ему, а не простоimport distutils
. В противном случае он может быть недоступен, и вы получите вышеуказанное,AttributeError
даже если оно там есть.Python 3.3 теперь предлагает shutil.which () .
источник
Для python 3.2 и более ранних версий:
Это одна строка ответа Джея , также здесь как лямбда-функция:
Или, наконец, с отступом в виде функции:
Для Python 3.3 и более поздних версий:
Как один из вкладышей Ян-Филип Gehrcke Ответ :
Как определение:
источник
x
где она должна бытьcmd
os.path.join(path, cmd)
это файл, нет? В конце концов, в каталогах также может быть установлен исполняемый бит ...mkdir -p -- "$HOME"/bin/dummy && PATH="$PATH":"$HOME"/bin && python -c 'import os; print any(os.access(os.path.join(path, "dummy"), os.X_OK) for path in os.environ["PATH"].split(os.pathsep))' && rmdir -- "$HOME"/bin/dummy
and os.path.isfile(...)
в соответствующие места достаточно, чтобы это исправитьПросто не забудьте указать расширение файла в Windows. В противном случае вам придется написать очень сложную
is_exe
для оконPATHEXT
переменную окружения. Вы можете просто использовать FindPath .OTOH, почему вы вообще пытаетесь найти исполняемый файл? Операционная система сделает это за вас как часть
popen
вызова и выдаст исключение, если исполняемый файл не найден. Все, что вам нужно сделать, это перехватить правильное исключение для данной ОС. Обратите внимание, что в Windowssubprocess.Popen(exe, shell=True)
произойдет сбой в автоматическом режиме, еслиexe
не найден.Включение
PATHEXT
в вышеупомянутую реализациюwhich
(в ответе Джея):источник
yield
inext_candidates
, дало мне лучшее понимание того, как работает это ключевое словоДля платформ * nix (Linux и OS X)
Кажется, это работает для меня:
Отредактирован для работы на Linux, благодаря Mestreion
Здесь мы используем встроенную команду
type
и проверяем код выхода. Если такой команды нет,type
выйдет с 1 (или ненулевым кодом состояния в любом случае).Немного о stdout и stderr - просто заставить замолчать вывод
type
команды, так как нас интересует только код состояния выхода.Пример использования:
источник
type
он встроен в оболочку, а не в исполняемый файл, поэтомуsubprocess.call()
здесь происходит сбой.OSError: [Errno 2] No such file or directory
. Может быть, в Mactype
есть актуальная командаshell=True
и заменить["type", cmd]
на"type " + cmd
Смотрите модуль os.path для некоторых полезных функций по путям. Чтобы проверить, является ли существующий файл исполняемым, используйте os.access (путь, режим) в режиме os.X_OK.
РЕДАКТИРОВАТЬ: В предлагаемых
which()
реализациях отсутствует одна подсказка - использованиеos.path.join()
для создания полных имен файлов.источник
На основании того, что проще просить прощения, чем разрешения я бы просто попытался использовать его и поймать ошибку (в данном случае OSError - я проверил, что файл не существует, и файл не является исполняемым, и они оба дают OSError).
Это помогает, если исполняемый файл имеет что-то вроде
--version
флага, который является быстрым запретом.Это не общее решение, но оно будет самым простым способом для многих случаев использования - тех, где код должен искать один хорошо известный исполняемый файл.
источник
--version
программу с именемlaunchmissiles
!launchmissies
существует ли, если вы не хотите запускать ракеты? Лучше выполнить его и действовать в зависимости от статуса / исключений при выходеgit
, для которых вы, вероятно, не хотите запускать вслепую.Я знаю, что я здесь немного некромант, но я наткнулся на этот вопрос, и принятое решение не сработало для меня во всех случаях. Думаю, что в любом случае было бы полезно отправить его. В частности, обнаружение «исполняемого» режима и требование предоставления расширения файла. Более того, и python3.3
shutil.which
(используетPATHEXT
), и python2.4 +distutils.spawn.find_executable
(просто пытается добавить'.exe'
) работают только в подмножестве случаев.Поэтому я написал «супер» версию (основываясь на принятом ответе и
PATHEXT
предложении Сураджа). Эта версияwhich
выполняет задачу немного более тщательно, сначала пробует серию «широкофазных» техник в ширину, и в конечном итоге пробует более детальный поиск вPATH
пространстве:Использование выглядит так:
Принятое решение не сделало работу для меня в этом случае, так как там было файлы , такие как
meld.1
,meld.ico
,meld.doap
и т.д. , также в каталоге, один из которых были возвращены вместо (предположительно , так как лексически первого) , так как исполняемый тест в общепринятом ответе был неполным и дают ложные срабатывания.источник
Лучшим примером должен быть встроенный модуль Python shutil.which () в Python 3. Ссылка: https://hg.python.org/cpython/file/default/Lib/shutil.py
источник
Я нашел что-то в StackOverflow, которое решило проблему для меня. Это работает при условии, что исполняемый файл имеет параметр (например, --help или --version), который выводит что-либо и возвращает нулевой статус выхода. См. Подавление вывода в вызовах Python для исполняемых файлов - «результат» в конце фрагмента кода в этом ответе будет нулевым, если исполняемый файл находится в пути, иначе он, скорее всего, будет равен 1.
источник
Это кажется достаточно простым и работает как в Python 2 и 3
источник
command -v executable
илиtype executable
быть универсальным. Есть случаи, когда на Macs не возвращает ожидаемых результатов.Важный вопрос: « Зачем вам нужно проверять, существует ли исполняемый файл?» Может, нет? ;-)
Недавно мне понадобился этот функционал, чтобы запустить просмотрщик для файла PNG. Я хотел перебрать несколько предопределенных зрителей и запустить первое из существующих. К счастью, я наткнулся
os.startfile
. Это гораздо лучше! Простой, переносимый и использует средство просмотра по умолчанию в системе:Обновление: я был неправ в отношении
os.startfile
переносимости ... Это только для Windows. На Mac вы должны запуститьopen
команду. Иxdg_open
на Unix. Существует проблема с Python при добавлении поддержки Mac и Unixos.startfile
.источник
Вы можете попробовать внешнюю библиотеку под названием "sh" ( http://amoffat.github.io/sh/ ).
источник
Добавлена поддержка Windows
источник
Вы можете сказать, существует ли файл с модулем os. в частности, исполняемый файл выглядит довольно непереносимым, учитывая, что на nix исполняется множество вещей, которых нет на windows, и наоборот.
источник
Казалось бы, очевидным выбором является «который», анализируя результаты с помощью popen, но вы можете смоделировать его в противном случае, используя класс os. В псевдопионе это будет выглядеть так:
источник
which
команды; Существует версия UnxUtils, но вы должны знать / указать расширение, иначе программа не будет найдена.Поэтому в основном вы хотите найти файл в смонтированной файловой системе (не обязательно только в каталогах PATH) и проверить, является ли он исполняемым. Это переводит на следующий план:
Я бы сказал, что это портативное решение потребует больших вычислительных ресурсов и времени. Это действительно то, что вам нужно?
источник
В стандартном дистрибутиве Python есть скрипт which.py (например, в Windows
'\PythonXX\Tools\Scripts\which.py'
) .РЕДАКТИРОВАТЬ:
which.py
зависит от,ls
поэтому он не кроссплатформенный.источник
Ни один из предыдущих примеров не работает на всех платформах. Обычно они не работают на Windows, потому что вы можете выполнить без расширения файла и что вы можете зарегистрировать новое расширение. Например, в Windows, если python хорошо установлен, достаточно запустить file.py, и он будет работать.
Единственное верное и переносимое решение, которое у меня было, - выполнить команду и увидеть код ошибки. Любой приличный исполняемый файл должен иметь набор параметров вызова, который ничего не будет делать.
источник
Используя библиотеку Python Fabric:
источник
which(1)
какая из них присутствует не во всех системах.