O essencial já é dado nas outras respostas. Tecnicamente, o shell armazena a localização de um comando em uma tabela de hash. Em bash
você pode ver esta tabela pelo comando hash
:
$ hash
hits command
2 /usr/bin/ldd
1 /usr/bin/man
1 /usr/bin/less
Você também pode modificar essa tabela de hash. Para detalhes, cito a página bash
man:
hash [-lr] [-p filename] [-dt] [name]
For each name, the full file name of the command is determined by searching the directories in $PATH and remembered. If
the -p option is supplied, no path search is performed, and filename is used as the full file name of the command.
The
-r option causes the shell to forget all remembered locations. The -d option causes the shell to forget the remembered
location of each name. If the -t option is supplied, the full pathname to which each name corresponds is printed. If
multiple name arguments are supplied with -t, the name is printed before the hashed full pathname. The -l option causes
output to be displayed in a format that may be reused as input. If no arguments are given, or if only -l is supplied,
information about remembered commands is printed. The return status is true unless a name is not found or an invalid
option is supplied. Here you can see, which commands you already executed in this session.
Outros shells podem se comportar de maneira diferente, em zsh
(e acho que isso foi adaptado de csh
) o shell reúne todo o comando na inicialização ou invocando rehash
. Então você obtém uma lista completa de todos os comandos disponíveis com hash
e você pode pesquisar, por exemplo para todas as variantes de diff
:
zsh$ hash | grep diff
bzdiff=/usr/bin/bzdiff
cdiff=/usr/bin/cdiff
colordiff=/usr/bin/colordiff
diff=/usr/bin/diff
diff3=/usr/bin/diff3
ptardiff=/usr/bin/ptardiff
sdiff=/usr/bin/sdiff
tkdiff=/usr/bin/tkdiff
vimdiff=/usr/bin/vimdiff
xzdiff=/usr/bin/xzdiff
zdiff=/usr/bin/zdiff
Mais uma vez, consulte man zshbuiltins
para mais detalhes.