Итак, я хотел установить Etherpad lite на Linux-машину. Если я попытаюсь запустить его, я получу ошибку:
«Пожалуйста, установите node.js (http://nodejs.org)"
команда which node
дает мне правильный путь к node js. Поэтому я зашел в файл .sh Etherpad Lite и нашел это:
#Is node installed?
hash node > /dev/null 2>&1 || {
echo "Please install node.js ( http://nodejs.org )" >&2
exit 1
}
Я думаю, это означает: проверить наличие узла --> если нет, вывести строку и выйти. Но что именно делает этот код? что делает хэш? Что со всеми этими &
и >
?
Буду очень признателен, если кто-нибудь сможет объяснить мне эти три строчки.
решение1
Когда вы вводите команды в оболочке bash, оболочка ищет эти команды по всей переменной $PATH. Хэш — это просто индекс команд, которые вы вводили, и где они были найдены, чтобы ускорить их поиск в следующий раз.
ПРИМЕЧАНИЕ: @Ответ Антонадает хорошее определение того, что такое хэш!
Например, если вы запустите только команду hash
без аргументов, вы получите список команд, которые были найдены ранее, а также количество раз, когда они использовались (т. е. количество совпадений):
% hash
hits command
2 /usr/bin/host
1 /bin/more
1 /home/saml/bin/autossh_mail.sh
3 /usr/bin/zip
2 /bin/rm
2 /bin/date
2 /usr/bin/vim
1 /usr/bin/htop
2 /bin/mv
3 /bin/ps
8 /usr/bin/ssh
1 /usr/bin/yum
1 /usr/bin/xfreerdp
1 /bin/cp
2 /bin/mkdir
4 /usr/bin/man
1 /usr/bin/gvim
1 /usr/bin/unzip
1 /usr/bin/w
5 /usr/bin/nslookup
51 /bin/ls
15 /usr/bin/find
Команда hash node
возвращает значение статуса (0 или 1) в зависимости от того, присутствовало ли это значение в списке хеша или нет:
hash node
нет в моем списке
% hash node
bash: hash: node: not found
% echo $?
1
ПРИМЕЧАНИЕ:Состояние любой ранее выполненной команды временно сохраняется в переменной среды.$?. Здесь отображается статус (0 = успешно, 1 = неудачно) после выполнения каждой команды.
Конструкция "cmd1" || { "cmd2" ... } является оператором or. Думайте здесь о and/or с точки зрения логики. Это означает, что нужно сделать первое действие, если оно не удается, то сделать второе, в противном случае не делать второе действие.
Более подробный пример:
% true && echo "1st cmd ret. 1" || echo "1st cmd ret. 0"
1st cmd ret. 1
% false && echo "1st cmd ret. 1" || echo "1st cmd ret. 0"
1st cmd ret. 0
Логика всегда запутанна (по крайней мере, для меня), поскольку возвращение 1 означает, что команда не выполнена, а возвращение 0 означает, что она выполнена успешно.
решение2
В дополнение к ранее опубликованным ответам я хотел бы добавить пояснение части «2>&1».
> /dev/null
Перенаправляет выходной файловый дескриптор (файловый дескриптор — это число, которое процесс использует для чтения и записи в файлы, каналы и терминал) в файл /dev/null, который является «мусорным баком» системы, поскольку он считывает все, что в него записывается, и отбрасывает эти данные.
2>&1
Перенаправляет файловый дескриптор stderr (выходной «файл» для ошибок) с номером 2 в файловый дескриптор 1, который только что был перенаправлен в /dev/null, т.е. проигнорирован.
Таким образом, обе эти части вместе гарантируют, что вывод команды hash не будет виден.
решение3
Из руководства bash:
Each time hash is invoked, the full pathname of the command name
is determined by searching the directories in $PATH and remembered.
Any previously-remembered pathname is discarded.
hash
— внутренняя команда bash, используемая для работы с хэш-таблицей, bash
которая используется для поиска полных путей к вводимым вами командам.
Этот скрипт использует его для обеспечения node
поиска исполняемого файла по указанному пути.
решение4
hash node
ищет PATH для первой команды с именем node и добавляет или обновляет местоположение node в списке запомненных местоположений или возвращает 1, если node не найден.
Вместо which используется hash, потому что:
- который не определен в POSIX.
- В некоторых средах это скрипт csh, который может изменять PATH.
- Например, в bash hash — это встроенная функция, а в которой ее нет, и hash обычно быстрее.
Как упомянул OP в комментарии, проблема была в том, что node на самом деле отсутствовал в PATH, когда скрипт был запущен. Поэтому which node
результат был бы тот же.