Problema al entender el comando 'hash' en un archivo .sh

Problema al entender el comando 'hash' en un archivo .sh

Entonces quería instalar Etherpad lite en una máquina Linux. Si intento ejecutarlo, obtendré el error:

"Por favor instale node.js (http://nodejs.org)"

el comando which nodeme da la ruta correcta al nodo js. Entonces entré en el archivo .sh de Etherpad Lite y encontré esto:

  #Is node installed?
  hash node > /dev/null 2>&1 || { 
  echo "Please install node.js ( http://nodejs.org )" >&2
  exit 1 
}

Supongo que significa: buscar nodo -> si no está disponible, imprimir la línea y salir. ¿Pero qué hace exactamente este código? ¿Qué hace el hachís? ¿Qué pasa con todo esto &y >?

¿Alguien que pueda explicarme estas 3 líneas se lo agradecería mucho?

Respuesta1

A medida que escribe comandos dentro de un shell bash, el shell busca esos comandos en la variable $PATH. El hash es solo un índice de los comandos que ha escrito y dónde se encontraron para ayudar a acelerar su búsqueda la próxima vez.

NOTA: La respuesta de @Anthon¡da una buena definición de qué es el hachís!

Por ejemplo, si ejecuta solo el comando hashsin argumentos, obtendrá una lista de los comandos que se encontraron anteriormente junto con cuántas veces se usaron (es decir, aciertos):

% 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

El comando hash nodedevuelve un valor de estado (0 o 1) dependiendo de si ese valor estaba presente en la lista de hash o no:

hash nodeno está en mi lista

% hash node
bash: hash: node: not found
% echo $?
1

NOTA:El estado de cualquier comando ejecutado previamente se almacena temporalmente en una variable de entorno.$?. Aquí es donde se coloca el estado (0 = éxito, 1 = error) después de ejecutar cada comando.

La construcción "cmd1" || { "cmd2" ... } es una declaración o. Pensar y/o desde la lógica aquí. Eso significa hacer lo primero, si falla, entonces hacer lo segundo, de lo contrario no hacer lo segundo.

Un ejemplo más elaborado:

% 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

La lógica siempre es confusa (al menos para mí) porque un 1 que se devuelve significa que el comando falló, mientras que un 0 que se devuelve significa que se ejecutó correctamente.

Respuesta2

Además de las respuestas publicadas anteriormente, me gustaría agregar una explicación de la parte "2>&1".

> /dev/null

Está redirigiendo el descriptor del archivo de salida (los descriptores de archivo son un número que el proceso usa para leer y escribir en archivos, tuberías y el terminal) al archivo /dev/null que es una "lata de almacenamiento" del sistema, ya que lee lo que sea escrito en él y descarta esos datos.

2>&1

Redirige el descriptor de archivo stderr (un "archivo" de salida para errores) que tiene el número 2 al descriptor de archivo 1, que acaba de ser redirigido a /dev/null, es decir, ignorado.

Entonces, ambas partes juntas aseguran que no se verá ningún resultado del comando hash.

Respuesta3

Del manual de 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.

hashes un comando interno para bash, que se utiliza para trabajar con la tabla hash bashpara buscar rutas completas a los comandos que escribe.

Este script lo utiliza para asegurarse de que nodese busque el ejecutable en la ruta.

Respuesta4

hash nodebusca en RUTA el primer comando llamado nodo y agrega o actualiza la ubicación del nodo en la lista de ubicaciones recordadas o devuelve 1 si no se encontró el nodo.

Se usa hash en lugar de which porque:

  • que no está definido por POSIX.
  • En algunos entornos, es un script csh que puede cambiar la RUTA.
  • Por ejemplo, en bash, el hash está integrado pero no lo es, y el hash suele ser más rápido.

Como mencionó el OP en un comentario, el problema fue que en realidad faltaba un nodo en PATH cuando se ejecutó el script. Entonces which nodehabría tenido el mismo resultado.

información relacionada