Liste toutes les commandes connues d'un shell

32

Que puis-je taper dans mon shell (qui se trouve être bash) qui listera toutes les commandes reconnues?

En outre, cela diffère-t-il par la coque? Ou est-ce que tous les shells ont juste un "répertoire" de commandes qu'ils reconnaissent?

Deuxièmement, une question différente, mais comment puis-je passer outre à celles-ci? En d'autres termes, comment puis-je écrire ma propre viewcommande pour remplacer celle qui existe sur mon système Ubuntu, qui semble juste se charger vim.

le miroir
la source
5
Veuillez ne pas combiner les questions. Postez chacun comme une question distincte.
terdon
Presque double de unix.stackexchange.com/q/63073/135943 (j'ai lié dans les deux directions.)
Wildcard

Réponses:

61

Vous pouvez utilisercompgen

compgen -c # will list all the commands you could run.

Pour info:

compgen -a # will list all the aliases you could run.
compgen -b # will list all the built-ins you could run.
compgen -k # will list all the keywords you could run.
compgen -A function # will list all the functions you could run.
compgen -A function -abck # will list all the above in one go.
Rahul Patil
la source
4
Notez que compgen -ccela inclura des choses comme {ou whilequi ne sont pas à proprement parler des commandes.
Stéphane Chazelas
13

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 ( ~/.bashrcpour 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 ( cdchange le répertoire courant, setchange les options et les paramètres de position, exportchange 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 PATHvariable 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 aliasinté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 setbuiltin répertorie les fonctions avec leurs définitions ainsi que les variables. En bash, ksh ou zsh, typeset -fré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 functionpour répertorier les commandes d'un type spécifique. Vous pouvez transmettre une chaîne supplémentaire à compgenpour 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 PATHvariable d'environnement ne contient pas ~/dir-for-wat-command, compgen -cne 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.

Gilles 'SO- arrête d'être méchant'
la source
Un autre cas de bord est pour les valeurs de $PATHlike /bin:/usr/bin:(fin :), où il ne parviendrait pas à répertorier les fichiers exécutables dans le répertoire en cours.
Stéphane Chazelas
3

La liste des commandes se compose de deux ensembles:

  1. Les commandes intégrées au shell
  2. Les commandes de votre PATH

Vous ne pouvez pas modifier les intégrés, mais vous pouvez empêcher le shell d'utiliser un intégré en spécifiant le chemin d'accès complet comme /bin/echo.

Quant aux commandes de votre PATH, vous pouvez changer cela. PATHest une liste de répertoires séparés par deux points pour rechercher des commandes. Le premier fichier correspondant a trouvé "gagne".

export PATH=~/bin:${PATH}

(Cette syntaxe ne fonctionne pas pour csh shells dérivés, mais tous les autres que je connais).

Cela s'exporte PATHavec ~/bincomme première entrée suivie du reste des PATHentrées existantes . Alors maintenant, votre shell va vérifier directory calledbin in your home directory for a command *first* before checking the standardPATH` la configuration du système. Vous pouvez facilement le faire vérifier le dernier répertoire en utilisant plutôt:

export PATH=${PATH}:~/bin

Pour faire PATHpersister pour les futures connexions, ajoutez-le à un .profileou à un autre fichier shell rc.

kurtm
la source
2

Essayez ceci, en utilisant :

printf '%s\n' ${PATH//:/\/* }
Gilles Quenot
la source
1

Si vous appuyez deux fois sur la touche de tabulation puis sur y, vous obtiendrez la liste de toutes les commandes disponibles dans votre shell actuel. Pour la deuxième question, je pense que vous devriez utiliser l'alias: shell alias .

coffeMug
la source
en ce qui concerne l'alias, est-ce une manière infaillible de surcharger et d'annuler (par "unaliasing") une commande lorsqu'elle est appelée n'importe où sur le système (par exemple à partir d'un script shell)?
themirror
1
Quelle coquille utilisez-vous? Je ne peux pas obtenir le double onglet pour répertorier toutes les commandes sur mon bash.
terdon
J'utilise bash sur Ubuntu 13.04. Il existe également une commande appelée compgen qui peut être utilisée pour obtenir la liste de toutes les commandes disponibles sur le bash.
coffeMug
@terdon Avez-vous installé la complétion bash?
coffeMug
1
mettre tout-en-un si ambigu
coffeMug