Как проверить,существует ли программа из скрипта Bash.

bash


Как я могу подтвердить существование программы таким образом,что она либо вернет ошибку и выйдет,либо продолжит работу со скриптом?

Похоже,это должно быть легко,но это меня озадачивает.




Answer 1 lhunath


Answer

совместимость с POSIX:

command -v <the_command>

Для особых условий Бэша:

hash <the_command> # For regular commands. Or...
type <the_command> # To check built-ins and keywords

Explanation

Избегайте which . Мало того, что это внешний процесс, который вы запускаете для выполнения очень мало (то есть встроенные hash , такие как хэш , type или command , намного дешевле), вы также можете полагаться на встроенные функции, которые действительно делают то, что вы хотите, в то время как эффекты внешних команд могут легко варьироваться от системы к системе.

Какая разница?

  • Многие операционные системы имеют which , что даже не установлен статус выхода , то есть , if which foo не будет работать даже там и будет всегда сообщать , что foo существует, даже если он не (заметим , что некоторые POSIX оболочки появляются делать это для hash тоже).
  • Многие операционные системы делают which то нестандартное и плохое, например, изменяют вывод или даже подключаются к менеджеру пакетов.

Так что не используйте which . Вместо этого используйте один из них:

$ command -v foo >/dev/null 2>&1 || { echo >&2 "I require foo but it's not installed.  Aborting."; exit 1; }
$ type foo >/dev/null 2>&1 || { echo >&2 "I require foo but it's not installed.  Aborting."; exit 1; }
$ hash foo 2>/dev/null || { echo >&2 "I require foo but it's not installed.  Aborting."; exit 1; }

(Незначительное замечание: некоторые предложат 2>&- это то же самое 2>/dev/null , но короче - это неверно . 2>&- закрывает FD 2, что вызывает ошибку в программе, когда она пытается записать в stderr , что сильно отличается от успешной записи в него и отбрасывания вывода (и опасно!))

Если ваш хэш-bang - /bin/sh , вам следует позаботиться о том, что говорит POSIX Коды выхода type и hash не очень хорошо определены в POSIX, и считается, что hash успешно завершается, когда команда не существует (еще не видел этого с type ). command статус выхода «сек хорошо определяется POSIX, так что один, вероятно , является самым безопасным для использования.

Если в вашем скрипте используется bash , правила POSIX больше не имеют значения, и type и hash становятся совершенно безопасными для использования. type теперь есть -P для поиска только PATH , а у hash есть побочный эффект, заключающийся в том, что расположение команды будет хэшировано (для более быстрого поиска в следующий раз, когда вы ее используете), что, как правило, хорошо, так как вы, вероятно, проверяете ее существование в Для того, чтобы на самом деле использовать его.

В качестве простого примера, вот функция, которая запускает gdate , если она существует, иначе date :

gnudate() {
    if hash gdate 2>/dev/null; then
        gdate "$@"
    else
        date "$@"
    fi
}

Альтернатива с полным набором функций

Вы можете использовать скрипты-общие для достижения ваших потребностей.

Проверить,установлено ли что-то или нет,можно:

checkBin <the_command> || errorMessage "This tool requires <the_command>. Install it please, and then run this tool again."



Answer 2 nyuszika7h


Ниже представлен переносимый способ проверить, существует ли команда в $PATH и является ли она исполняемой:

[ -x "$(command -v foo)" ]

Example:

if ! [ -x "$(command -v git)" ]; then
  echo 'Error: git is not installed.' >&2
  exit 1
fi

Проверка исполняемого файла необходима, поскольку bash возвращает неисполняемый файл, если в $PATH найден исполняемый файл с таким именем .

Также обратите внимание, что если в $PATH ранее не существует исполняемого файла с тем же именем, что и у исполняемого файла , то он возвращает первый, даже если последний будет выполнен. Это ошибка, которая нарушает стандарт POSIX. [ Отчет об ошибке ] [ Стандарт ]

Кроме того,это будет неудачно,если команда,которую вы ищете,была определена как псевдоним.




Answer 3 GregV


Я согласен с lhunath воздерживаться от использования which , и его решение совершенно справедливо для пользователей Bash . Однако для большей переносимости вместо command -v следует использовать команду -v :

$ command -v foo >/dev/null 2>&1 || { echo "I require foo but it's not installed.  Aborting." >&2; exit 1; }

Командная command соответствует POSIX. Смотрите здесь для его спецификации: команда - выполнить простую команду

Примечание: type совместим с POSIX, а type -P - нет.




Answer 4 Josh Strater


У меня есть функция,определенная в моем .bashrc,которая делает это проще.

command_exists () {
    type "$1" &> /dev/null ;
}

Вот пример того, как он используется (из моего .bash_profile .)

if command_exists mvim ; then
    export VISUAL="mvim --nofork"
fi



Answer 5 dreamlax


Это зависит от того, хотите ли вы узнать, существует ли он в одном из каталогов в $PATH или знаете ли вы его абсолютное местоположение. Если вы хотите узнать, находится ли она в $PATH , используйте

if which programname >/dev/null; then
    echo exists
else
    echo does not exist
fi

иное использование

if [ -x /path/to/programname ]; then
    echo exists
else
    echo does not exist
fi

Перенаправление на /dev/null/ в первом примере подавляет вывод which программы.