Я пишу свою первую оболочку 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 "$@"; do
if ! which $var &> /dev/null; then
echo "Install $var!"
exit 1
fi
done
}
Пример вызова:
assertInstalled zsh vim wget python pip git cmake fc-cache