Problema ao entender o comando 'hash' em um arquivo .sh

Problema ao entender o comando 'hash' em um arquivo .sh

Então eu queria instalar o Etherpad Lite em uma máquina Linux. Se eu tentar executá-lo, receberei o erro:

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

o comando which nodeme fornece o caminho correto para o nó js. Então entrei no arquivo .sh do Etherpad Lite e encontrei isto:

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

Eu acho que significa: verifique o nó -> se não estiver disponível, imprima a linha e saia. Mas o que exatamente esse código faz? o que o hash faz? O que há com tudo isso &e >?

Alguém que possa me explicar essas 3 linhas ficaria muito grato?

Responder1

Conforme você digita comandos em um shell bash, o shell procura esses comandos em toda a variável $PATH. O hash é apenas um índice de quais comandos você digitou e onde eles foram encontrados para ajudar a acelerar a localização deles na próxima vez.

OBSERVAÇÃO: Resposta de @Anthondá uma boa definição do que é hash!

Por exemplo, se você executar apenas o comando hashsem argumentos, você obterá uma lista de quais comandos foram encontrados anteriormente junto com quantas vezes eles foram usados ​​(ou seja: hits):

% 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

O comando hash noderetorna um valor de status (0 ou 1) dependendo se esse valor estava presente na lista de hash ou não:

hash nodenão está na minha lista

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

OBSERVAÇÃO:O status de qualquer comando executado anteriormente é armazenado temporariamente em uma variável de ambiente$?. É aqui que o status (0 = sucesso, 1 = falha) é colocado após cada comando ser executado.

A construção "cmd1" || { "cmd2" ... } é uma instrução ou. Pense e/ou a partir da lógica aqui. Então isso significa fazer a primeira coisa, se falhar, então faça a segunda, caso contrário não faça a segunda coisa.

Um exemplo mais 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

A lógica é sempre confusa (pelo menos para mim) porque o retorno de 1 significa que o comando falhou, enquanto o retorno de 0 significa que ele foi executado com sucesso.

Responder2

Além das respostas postadas anteriormente, gostaria de acrescentar uma explicação da parte "2>&1".

> /dev/null

Está redirecionando o descritor do arquivo de saída (descritores de arquivo são um número que o processo usa para ler e gravar em arquivos, pipes e no terminal) para o arquivo /dev/null que é uma "lata de recolha" do sistema, pois lê o que quer que seja gravado nele e descarta esses dados.

2>&1

Redireciona o descritor de arquivo stderr (um "arquivo" de saída para erros) que é numerado 2 para o descritor de arquivo 1, que foi redirecionado para /dev/null, ou seja, ignorado.

Portanto, ambas as partes juntas garantem que nenhuma saída será vista no comando hash.

Responder3

Do manual do 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é um comando interno para bash, usado para trabalhar com a tabela hash bashpara procurar caminhos completos para comandos que você digita.

Este script o utiliza para garantir que o nodeexecutável seja pesquisado no caminho.

Responder4

hash nodepesquisa PATH pelo primeiro comando denominado node e adiciona ou atualiza a localização do nó na lista de locais lembrados ou retorna 1 se o nó não foi encontrado.

hash é usado em vez de which porque:

  • que não é definido pelo POSIX.
  • Em alguns ambientes, é um script csh que pode alterar o PATH.
  • Por exemplo, no bash, o hash é um recurso interno, mas não é, e o hash geralmente é mais rápido.

Como o OP mencionou em um comentário, o problema era que o nó estava faltando no PATH quando o script foi executado. Então which nodeteria tido o mesmo resultado.

informação relacionada