¿Por qué `type which` dice that` which hash`?


31

En el caso de los depósitos incorporados (p. Ej., En typesí):

$ type type
type is a shell builtin

$ which type
<Doesn't return anything since it's a shell builtin, silently exits>

En caso de comandos (normalmente) (por ejemplo python):

$ type python
python is /usr/bin/python

$ which python
/usr/bin/python

En caso de which(que es un comando ubicado en /usr/bin/which)

$ type which
which is hashed (/usr/bin/which)
$ which which
/usr/bin/which

¿Por qué type whichdice eso which is hashed? ¿Cuál es el significado de whichser hash y qué significa realmente?

Respuestas:


41

Es probable que tenga un conjunto de RUTA largo y, para encontrar un ejecutable, el shell necesita buscar la ruta. Para evitar ese proceso lento cada vez que desea ejecutar un programa, el shell puede mantener una lista de programas que ya ha encontrado. Esa lista se llama "hash". Cuando el shell dice que whichestá en hash, significa que ya ha realizado la búsqueda de RUTA y ha encontrado whichy guardado su ubicación en el hash.

man bash lo explica de la siguiente manera:

Bash usa una tabla hash para recordar los nombres completos de las rutas de los archivos ejecutables (vea el hash debajo de COMANDOS SHELL BUILTIN a continuación). Se realiza una búsqueda completa de los directorios en PATH solo si el comando no se encuentra en la tabla hash.

Si bien el hash normalmente acelera las operaciones de shell, hay un caso en el que causa problemas. Si actualiza su sistema y, como resultado, algunos ejecutables se mueven a una nueva ubicación, el shell puede confundirse. La solución es ejecutar, lo hash -rque hace que el shell olvide todas las ubicaciones hash y busque la RUTA desde cero.

¿Por qué faltan algunos ejecutables del hash?

Un ejecutable no se coloca en el hash hasta después de ejecutarlo al menos una vez. Observar:

$ type python
python is /usr/bin/python
$ python --version
Python 2.7.3
$ type python
python is hashed (/usr/bin/python)

python se procesa solo después de que se haya ejecutado.

Cómo examinar lo que hay en el hash de bash

El contenido del hash está disponible en la bashmatriz BASH_CMDS. Puedes ver lo que contiene con el comando declare -p BASH_CMDS. Cuando se abre un nuevo shell o subshell, el hash está vacío. Los comandos se agregan uno por uno a medida que se usan. Desde un caparazón recién abierto, observe:

$ declare -p BASH_CMDS
declare -A BASH_CMDS='()'
$ which which
/bin/which
$ declare -p BASH_CMDS
declare -A BASH_CMDS='([which]="/bin/which" )'
$ python --version
Python 2.7.3
$ declare -p BASH_CMDS
declare -A BASH_CMDS='([which]="/bin/which" [python]="/usr/bin/python" )'

+1, muy buena explicación. ¿Pero por qué whichy no para python?
jobin

@Jobin Ver respuesta actualizada.
John1024

2
Parece que el hash persiste solo hasta el momento en que no salimos del shell. Una vez que reiniciamos la terminal, no dice que el comando está en hash.
Aditya

1
@Aditya Sí. Agregué una sección sobre eso a la respuesta.
John1024

hash -lsería más fácil de usar quedeclare -p BASH_CMDS
phuclv
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.