O que significa "rm is hashed"?

58

Estou passando por http://mywiki.wooledge.org/BashGuide/CommandsAndArguments e me deparei com isso:

$ type rm
rm is hashed (/bin/rm)
$ type cd
cd is a shell builtin

Um pouco antes, o guia listou os vários tipos de comandos entendidos pelo Bash: aliases, funções, builtins, palavras-chave e executáveis. Mas não houve menção a "hash". Então, nesse contexto, o que significa "hash"?

Gilles 'SO- parar de ser mau'
fonte

Respostas:

59

É uma coisa de desempenho; em vez de procurar o caminho inteiro pelo binário toda vez que é chamado, ele é colocado em uma tabela de hash para uma pesquisa mais rápida. Portanto, qualquer binário que já esteja nessa tabela de hash é hash. Se você mover os binários quando eles já estiverem com hash, ele ainda tentará chamá-los no local antigo.

Veja também help hash, ou man bashe procure por hashcomandos embutidos lá.

frostschutz
fonte
15

Como outros usuários mencionaram, o hash é uma matriz associativa (chave -> valor) que o Bash mantém, de modo que, quando um comando é executado, o Bash pesquisa esse hash primeiro para ver se a localização do comando no disco já foi encontrada $PATHe armazenada lá para uma pesquisa mais rápida.

Você pode pré-carregar o hash fornecendo uma lista de comandos que você deseja que o Bash encontre quando for chamado. Essa variável é chamada BASH_CMDS.

trecho da página do manual

   BASH_CMDS
          An  associative  array  variable  whose members correspond to the 
          internal hash table of commands as maintained by the hash builtin.
          Elements added to this array appear in the hash table; unsetting 
          array elements cause commands to be removed from the hash table.

Além disso, se você olhar a página de manual do Bash, há uma seção intitulada COMMAND EXECUTION que detalha a máquina de estado que o Bash usa quando um comando é digitado no prompt.

excerto

   If the name is neither a shell function nor a builtin, and contains no 
   slashes, bash searches each element of the PATH for a directory con
   taining an executable file by that name.  Bash uses a hash table to 
   remember the full pathnames of executable files (see hash  under  SHELL
   BUILTIN COMMANDS below).  A full search of the directories in PATH is 
   performed only if the command is not found in the hash table.  If the
   search is unsuccessful, the shell searches for a defined shell function 
   named command_not_found_handle.  If that  function  exists,  it  is
   invoked  with  the  original command and the original command's arguments 
   as its arguments, and the function's exit status becomes the exit
   status of the shell.  If that function is not defined, the shell prints 
   an error message and returns an exit status of 127.

Você pode descobrir o que está atualmente em seu hash usando o -lswitch.

Exemplo

$ hash -l
builtin hash -p /usr/bin/rm rm
builtin hash -p /usr/bin/sudo sudo
builtin hash -p /usr/bin/man man
builtin hash -p /usr/bin/ls ls
slm
fonte
muito útil obrigado. Enquanto estou trabalhando em um script, acho que esse hash atrapalha. Existe uma maneira de desativar ou limpar isso?
qodeninja 23/08
10

hash é um shell Bash embutido que fornece hash para comandos.

hash [-lr] [-p filename] [-dt] [name]

Diretamente da boca do cavalo:

help hash

Lembre-se ou exiba os locais do programa.

info Bash → Comandos do Shell Builtin → Bourne Shell Builtins

Lembre-se dos nomes de caminho completos dos comandos especificados como argumentos NAME, para que eles não precisem ser pesquisados ​​nas chamadas subseqüentes. Os comandos são encontrados pesquisando nos diretórios listados em $PATH. A -popção inibe a pesquisa de caminho e FILENAME é usado como o local de NAME. A -ropção faz com que o shell esqueça todos os locais lembrados. A -dopção faz com que o shell esqueça o local lembrado de cada NAME. Se a -topção for fornecida, o nome do caminho completo ao qual cada NAME corresponde é impresso. Se vários argumentos NAME forem fornecidos, -to NAME será impresso antes do nome completo do caminho do hash. A -lopção faz com que a saída seja exibida em um formato que possa ser reutilizado como entrada. Se nenhum argumento for fornecido, ou se apenas-lé fornecida, as informações sobre comandos lembrados são impressas. O status de retorno é zero, a menos que um NAME não seja encontrado ou uma opção inválida seja fornecida.

Ruban Savvy
fonte