Проблема с пониманием команды «хеш» в файле .sh

Проблема с пониманием команды «хеш» в файле .sh

Итак, я хотел установить 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результат был бы тот же.

Связанный контент