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 node
me 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 hash
sin 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 node
devuelve un valor de estado (0 o 1) dependiendo de si ese valor estaba presente en la lista de hash o no:
hash node
no 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.
hash
es un comando interno para bash, que se utiliza para trabajar con la tabla hash bash
para buscar rutas completas a los comandos que escribe.
Este script lo utiliza para asegurarse de que node
se busque el ejecutable en la ruta.
Respuesta4
hash node
busca 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 node
habría tenido el mismo resultado.