Un shell connaît quatre types de commandes.
- Alias: ce sont des surnoms pour une commande avec quelques options. Ils sont définis dans le fichier d'initialisation du shell (
~/.bashrc
pour bash).
- Fonctions: ce sont des extraits de code shell nommés. Comme les alias, ils sont définis dans le fichier d'initialisation du shell.
- Builtins: le shell est livré avec un petit nombre de commandes intégrées. La plupart des builtins manipulent l'état du shell (
cd
change le répertoire courant, set
change les options et les paramètres de position, export
change l'environnement,…). La plupart des shell offrent en grande partie les mêmes fonctions internes, mais chaque shell a quelques extensions de l'ensemble de base.
- Commandes externes: elles sont indépendantes du shell. Comme d'autres programmes, le shell exécute des programmes externes en les recherchant dans le chemin de recherche exécutable . La
PATH
variable d'environnement contient une liste de répertoires séparés par deux points pour rechercher des programmes.
En cas de commandes de plusieurs types portant le même nom, la première correspondance dans l'ordre ci-dessus est exécutée¹.
Vous pouvez voir à quel type de commande correspond un nom en exécutant type some_name
.
Vous pouvez répertorier les alias en exécutant la fonction alias
intégrée sans argument. Il n'y a aucun moyen de lister les fonctions ou les builtins qui fonctionnent dans tous les shells. Vous pouvez trouver une liste de builtins dans la documentation du shell.
En bash, le set
builtin répertorie les fonctions avec leurs définitions ainsi que les variables. En bash, ksh ou zsh, typeset -f
répertorie les fonctions avec leurs définitions. En bash, vous pouvez lister tous les noms de commandes de tout type avec compgen -c
. Vous pouvez utiliser compgen -A alias
, compgen -A builtin
compgen -A function
pour répertorier les commandes d'un type spécifique. Vous pouvez transmettre une chaîne supplémentaire à compgen
pour répertorier uniquement les commandes commençant par ce préfixe.
En zsh, vous pouvez lister les commandes actuellement disponibles d'un type donné avec echo ${(k)aliases}
, echo ${(k)functions}
, echo ${(k)builtins}
et echo ${(k)commands}
(que la dernière listes de commandes externes uniquement).
L'extrait de code shell-agnostique suivant répertorie tous les programmes externes disponibles:
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
Il y a un cas de bord dans les commandes Bash: hachées.
Le manuel de référence de Bash dit:
Une recherche complète des répertoires dans $ PATH n'est effectuée que si la commande n'est pas trouvée dans la table de hachage
Essayer:
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
variable d'environnement ne contient pas ~/dir-for-wat-command
, compgen -c
ne s'affiche pas wat
, mais vous pouvez exécuter wat
.
Si vous souhaitez masquer une commande existante, définissez un alias ou une fonction .
¹ Exception: quelques fonctions internes (appelées fonctions spéciales ) ne peuvent pas être masquées par une fonction - bash et zsh ne sont cependant pas conformes à POSIX sur ce point dans leur mode par défaut.