Um shell conhece quatro tipos de comandos.
- Alias: são apelidos para um comando com algumas opções. Eles são definidos no arquivo de inicialização do shell (
~/.bashrc
para bash).
- Funções: são trechos de código shell que recebem um nome. Como aliases, eles são definidos no arquivo de inicialização do shell.
- Builtins: o shell vem com um pequeno número de comandos embutidos. A maioria dos builtins manipula o estado do shell (
cd
altera o diretório atual, set
altera opções e parâmetros posicionais, export
altera o ambiente, ...). A maioria dos shell oferece basicamente os mesmos recursos internos, mas cada shell possui algumas extensões para o conjunto básico.
- Comandos externos: eles são independentes do shell. Como outros programas, o shell executa programas externos procurando-os no caminho da pesquisa executável . A
PATH
variável de ambiente contém uma lista de diretórios separados por dois pontos para procurar programas.
Caso existam comandos de vários tipos com o mesmo nome, a primeira correspondência na ordem acima é executada¹.
Você pode ver a que tipo de comando um nome corresponde executando type some_name
.
Você pode listar aliases executando o alias
built-in sem argumento. Não há como listar funções ou componentes internos que funcionem em todos os shells. Você pode encontrar uma lista de componentes internos na documentação do shell.
No bash, o set
built-in lista funções com suas definições e variáveis. No bash, ksh ou zsh, typeset -f
lista funções com suas definições. No bash, você pode listar todos os nomes de comandos de qualquer tipo compgen -c
. Você pode usar compgen -A alias
, compgen -A builtin
compgen -A function
para listar comandos de um tipo específico. Você pode passar uma sequência adicional compgen
para listar apenas os comandos que começam com esse prefixo.
Em zsh, você pode listar os comandos disponíveis atualmente de um determinado tipo com echo ${(k)aliases}
, echo ${(k)functions}
, echo ${(k)builtins}
e echo ${(k)commands}
(apenas essa última lista os comandos externos).
O seguinte snippet independente de shell lista todos os programas externos disponíveis:
case "$PATH" in
(*[!:]:) PATH="$PATH:" ;;
esac
set -f; IFS=:
for dir in $PATH; do
set +f
[ -z "$dir" ] && dir="."
for file in "$dir"/*; do
if [ -x "$file" ] && ! [ -d "$file" ]; then
printf '%s = %s\n' "${file##*/}" "$file"
fi
done
done
Há um caso de borda no Bash: comandos de hash.
O Manual de Referência do Bash diz:
Uma pesquisa completa dos diretórios em $ PATH é executada apenas se o comando não for encontrado na tabela de hash
Experimentar:
set -h
mkdir ~/dir-for-wat-command
echo 'echo WAT!' >~/dir-for-wat-command/wat
chmod +x ~/dir-for-wat-command/wat
hash -p ~/dir-for-wat-command/wat wat
wat
A PATH
variável de ambiente não contém ~/dir-for-wat-command
, compgen -c
não aparece wat
, mas você pode executar wat
.
Se você deseja sombrear um comando existente, defina um alias ou uma função .
Ception Exceção: alguns built-in (chamados built-in especiais ) não podem ser sombreados por uma função - o bash e o zsh não estão de acordo com o POSIX nesse ponto no modo padrão.