Comando de compreensão de problemas 'hash' em um arquivo .sh

4

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

"Please install node.js ( http://nodejs.org )"

o comando which node me fornece o caminho correto para o nó js. Então eu fui para o arquivo .sh do Etherpad Lite e achei isso:

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

Acho que significa: verifique o nó - > se não estiver disponível, imprima e saia. Mas o que exatamente esse código faz? o que o hash faz? O que há com todos esses & e > ?

Alguém que possa me explicar essas 3 linhas seria muito apreciado?

    
por Yalla T. 23.04.2013 / 17:09

4 respostas

3

Conforme você digita comandos dentro de um shell bash, o shell está procurando por aqueles comandos através da variável $ PATH. O hash é apenas um índice de quais comandos você digitou e onde eles foram encontrados para ajudar a acelerar a descoberta deles na próxima vez.

NOTA: @ resposta do Anthon dá uma boa definição do que hash é!

Por exemplo, se você executar apenas o comando hash sem argumentos, obterá uma lista de quais comandos foram encontrados anteriormente junto com quantas vezes eles foram usados (por exemplo, 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 node retorna um valor de status (0 ou 1) dependendo se esse valor estava presente na lista de hash ou não:

hash node não está na minha lista

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

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

A construção "cmd1" || {"cmd2" ...} é uma declaração ou. Pense e / ou 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 um 1 sendo retornado significa que o comando falhou, enquanto um 0 sendo retornado significa que ele foi executado com êxito.

    
por 23.04.2013 / 17:49
3

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

> /dev/null

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

2>&1

Redireciona o descritor de arquivo stderr (um arquivo de saída para erros) que é numerado como 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 pelo comando hash.

    
por 23.04.2013 / 20:55
1

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 de hash bash usa para procurar caminhos completos para os comandos digitados.

Este script usa-o para garantir que o executável node seja pesquisado no caminho.

    
por 23.04.2013 / 17:29
0

hash node procura o PATH para o primeiro comando chamado node e adiciona ou atualiza o local do nó na lista de locais lembrados ou retorna 1 se o nó não foi encontrado.

O hash

é usado em vez de porque:

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

Como o OP mencionado em um comentário, o problema era que o nó estava ausente do PATH quando o script foi executado. Então, which node teria o mesmo resultado.

    
por 23.04.2013 / 19:45