k.sh
:
if ! [ -x "$(command -v nvm)" ]; then
echo 'Error: nvm is not installed' >&2
else
echo 'nvm installed'
fi
Терминал:
km@Karl ~/dev/cac (master) $ nvm --version
0.33.2
km@Karl ~/dev/cac (master) $ . k.sh
Error: nvm is not installed
Я бы хотел, чтобы bash проверил, существует ли команда! Источниками NVM являются .bash_profile
и .bashrc
.
@KamilCuk Работает! Хотите ответить и объяснить, почему мой код не работает?
[ -x ]
проверяет, существует ли файл и является ли он исполняемым. Он потерпит неудачу, если вы передадите имя функции оболочки или псевдоним. В дополнительной проверке нет необходимости. Достаточно просто проверить, удалось ли выполнить command
.
if ! command -v nvm &> /dev/null
hash
для меня самый портативный:
if hash nvm 2>/dev/null; then echo exists; else echo does not exist; fi
Почему не работает? Посмотрим, что вы делаете:
command -v nvm
# ничего не печатает и выходит с 1$(command -v nvm)
# ничего не печатает и выходит с 1
Статус выхода команды [ -x "$(command -v nvm)" ]
игнорируется. Имеет значение только строка, возвращаемая командой. Так оно и выполняется:
Команда тестирования [ -x "" ]
завершается со статусом 1, так как файл ""
не является исполняемым (такой файл не существует) .! [ -x "" ]
, тогда вы отменяете статус возврата, поэтому он возвращает 0, то есть истина
Если вы хотите использовать команду -v, чтобы проверить, существует ли файл, проверьте его статус возврата, а не строку:
if command -v nvm 2>/dev/null; then echo exists; else echo does not exist; fi
Но хеш немного более переносимый, лучше придерживаться хеша.
Чем hash
более портативен, чем command
? Оба определены POSIX.
После прочтения это я теперь убежден в пользу команды. Во втором ответе даже есть [ -x "$(command -v foo)" ]
, так что сейчас я озадачен.
Это проверка чего-то другого. С этой командой foo
должен быть не только командой, но и исполняемым файлом, а не псевдонимом, функцией или встроенной оболочкой.
if hash nvm 2>/dev/null; then echo exists; else echo does not exist; fi