Как проверить, существует ли команда в оболочке script?

Я пишу свою первую оболочку script. В моем script я хотел бы проверить, существует ли определенная команда, а если нет, установите исполняемый файл. Как проверить, существует ли эта команда?

if #check that foobar command doesnt exist
then
    #now install foobar
fi

Ответ 1

В общем, это зависит от вашей оболочки, но если вы используете bash, zsh, ksh или sh (как указано в тире), должно работать следующее:

if ! type "$foobar_command_name" > /dev/null; then
  # install foobar here
fi

Для реальной установки script вы, вероятно, захотите убедиться, что type не возвращается успешно в случае, если имеется псевдоним foobar. В bash вы можете сделать что-то вроде этого:

if ! foobar_loc="$(type -p "$foobar_command_name")" || [ -z "$foobar_loc" ]; then
  # install foobar here
fi

Ответ 2

попробуйте использовать type:

type foobar

Например:

$ type ls
ls is aliased to `ls --color=auto'

$ type foobar
-bash: type: foobar: not found

Это предпочтительнее which по нескольким причинам:

1) реализация по умолчанию which поддерживает только параметр -a, который показывает все параметры, поэтому вам нужно найти альтернативную версию для поддержки псевдонимов

2) тип скажет вам точно, на что вы смотрите (будь это функция bash или псевдоним или правильный двоичный файл).

3) тип не требует подпроцесса

4) тип не может быть замаскирован двоичным (например, в окне linux, если вы создаете программу под названием which, которая появляется в пути до реального which, все попадает в вентилятор. type, с другой стороны, является встроенной оболочкой [да, подчиненный случайно сделал это один раз]

Ответ 3

Проверьте, действительно ли программа существует из Bash script. В любой оболочке script вам лучше запускать command -v $command_name для тестирования, если можно запустить $command_name. В Bash вы можете использовать hash $command_name, который также хэширует результат любого поиска пути или type -P $binary_name, если вы хотите видеть только двоичные файлы (не функции и т.д.).

Ответ 4

Вопрос не определяет оболочку, поэтому для тех, кто использует fish (дружественная интерактивная оболочка):

if command --search foo >/dev/null do
  echo exists
else
  echo does not exist
end

Для базовой совместимости с POSIX используйте флаг -v, который является псевдонимом для --search или -s.

Ответ 5

Пять способов, 4 для bash и 1 дополнение для zsh:

  • type foobar &> /dev/null
  • hash foobar &> /dev/null
  • command -v foobar &> /dev/null
  • which foobar &> /dev/null
  • (( $+commands[foobar] )) (только zsh)

Вы можете поместить любой из них в свое предложение if. Согласно моим тестам (https://www.topbug.net/blog/2016/10/11/speed-test-check-the-existence-of-a-command-in-bash-and-zsh/), первый и третий методы рекомендуются в bash, а 5-й метод рекомендуется в zsh в терминах скорости.

Ответ 6

which <cmd>

также см. опции which поддерживает для псевдонимов, если применимо к вашему делу.

Пример

$ which foobar
which: no foobar in (/usr/local/bin:/usr/bin:/cygdrive/c/Program Files (x86)/PC Connectivity Solution:/cygdrive/c/Windows/system32/System32/WindowsPowerShell/v1.0:/cygdrive/d/Program Files (x86)/Graphviz 2.28/bin:/cygdrive/d/Program Files (x86)/GNU/GnuPG
$ if [ $? -eq 0 ]; then echo "foobar is found in PATH"; else echo "foobar is NOT found in PATH, of course it does not mean it is not installed."; fi
foobar is NOT found in PATH, of course it does not mean it is not installed.
$

PS: Обратите внимание, что не все, что установлено, может быть в PATH. Обычно, чтобы проверить, установлено ли что-либо, или нет, будут использоваться связанные с установкой команды, относящиеся к ОС. Например. rpm -qa | grep -i "foobar" для RHEL.

Ответ 7

Функция, которую я имею в установке script, сделанной именно для этого

function assertInstalled() {
    for var in "[email protected]"; do
        if ! which $var &> /dev/null; then
            echo "Install $var!"
            exit 1
        fi
    done
}

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

assertInstalled zsh vim wget python pip git cmake fc-cache