Una shell conosce quattro tipi di comandi.
- Alias: sono soprannomi per un comando con alcune opzioni. Sono definiti nel file di inizializzazione della shell (
~/.bashrc
per bash).
- Funzioni: sono frammenti di codice shell con un nome. Come gli alias, sono definiti nel file di inizializzazione della shell.
- Builtins: la shell ha un piccolo numero di comandi integrati. La maggior parte dei builtin manipola lo stato della shell (
cd
cambia la directory corrente, set
cambia le opzioni e i parametri posizionali, export
cambia l'ambiente, ...). La maggior parte delle shell offre in gran parte gli stessi builtin ma ogni shell ha alcune estensioni al set di base.
- Comandi esterni: sono indipendenti dalla shell. Come altri programmi, la shell esegue programmi esterni cercandoli nel percorso di ricerca eseguibile . La
PATH
variabile di ambiente contiene un elenco separato da due punti di directory per la ricerca di programmi.
Nel caso in cui vi siano comandi di diversi tipi con lo stesso nome, viene eseguita la prima corrispondenza nell'ordine sopra¹.
Puoi vedere a quale tipo di comando corrisponde un nome eseguendo type some_name
.
È possibile elencare gli alias eseguendo il alias
built-in senza alcun argomento. Non è possibile elencare funzioni o builtin che funzionano in tutte le shell. È possibile trovare un elenco di builtin nella documentazione della shell.
In bash, il set
builtin elenca le funzioni con le loro definizioni e variabili. In bash, ksh o zsh, typeset -f
elenca le funzioni con le loro definizioni. In bash, puoi elencare tutti i nomi dei comandi di qualsiasi tipo con compgen -c
. È possibile utilizzare compgen -A alias
, compgen -A builtin
compgen -A function
per elencare i comandi di un tipo specifico. È possibile passare una stringa aggiuntiva compgen
per elencare solo i comandi che iniziano con quel prefisso.
In zsh, è possibile elencare i comandi attualmente disponibili di un determinato tipo con echo ${(k)aliases}
, echo ${(k)functions}
, echo ${(k)builtins}
e echo ${(k)commands}
(solo che l'ultimo elenca i comandi esterni).
Il seguente frammento di shell-agnostico elenca tutti i programmi esterni disponibili:
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
C'è un caso limite in Bash: comandi con hash.
Il manuale di riferimento di Bash dice:
Una ricerca completa delle directory in $ PATH viene eseguita solo se il comando non viene trovato nella tabella hash
Provare:
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
La PATH
variabile d'ambiente non contiene ~/dir-for-wat-command
, compgen -c
non mostra wat
, ma puoi eseguirla wat
.
Se si desidera ombreggiare un comando esistente, definire un alias o una funzione .
¹ Eccezione: alcuni builtin (chiamati builtins speciali ) non possono essere ombreggiati da una funzione - bash e zsh non sono conformi a POSIX su quel punto nella loro modalità predefinita.