Quelle est la différence entre quoi et où

16

Quelle est la différence entre les commandes shell whereet which? Voici quelques exemples

 ~  where cc
/usr/bin/cc
/usr/bin/cc
~  which cc
/usr/bin/cc

et

  ~  which which
which='alias | /usr/bin/which --tty-only --read-alias --show-dot --show-tilde'
/usr/bin/which
  ~  which where
/usr/bin/which: no where in (/usr/local/bin:/bin:/usr/bin:/home/bnikhil/bin:/bin)

aussi

  ~  where which
which: aliased to alias | /usr/bin/which --tty-only --read-alias --show-dot
 --show-tilde
which: shell built-in command
/usr/bin/which
/usr/bin/which
  ~  where where
where: shell built-in command

Pour moi, il semble qu'ils font la même chose l'un étant un shell intégré, pas tout à fait sûr de la différence avec une commande?

nikhil
la source

Réponses:

11

zshest l'un des rares shells (les autres étant tcsh(à l' whichorigine un cshscript pour les cshutilisateurs, qui avait aussi sa limitation, en a tcshfait un intégré comme une amélioration)) où whichfait quelque chose de sensé car c'est un shell intégré, mais en quelque sorte vous ou votre système d'exploitation (via un rcfichier) l'a cassé en le remplaçant par un appel à la whichcommande système qui ne peut rien faire de manière fiable car il n'a pas accès aux internes du shell donc ne peut pas savoir comment ce shell interprète un nom de commande .

En zsh, tous which, type, whenceet wheresont des commandes qui sont builtin tous utilisés pour en savoir plus sur ce que les commandes sont, mais avec des sorties différentes. Ils sont tous là pour des raisons historiques, vous pouvez obtenir tous les comportements avec des drapeaux différents pour la whencecommande.

Vous pouvez obtenir les détails de ce que chacun fait en exécutant:

info -f zsh --index-search=which

Ou tapez info zsh, puis iaffichez l'index avec et entrez le nom intégré (l'achèvement est disponible).

Et évitez d'utiliser /usr/bin/which. Il n'y a pas d'obus de nos jours là où cela which est nécessaire. Comme le dit Timothy, utilisez la fonction intégrée que votre shell fournit pour cela. La plupart des shells POSIX auront la typecommande, et vous pouvez utiliser command -vpour obtenir uniquement le chemin d'une commande (bien que les deux typeet command -vsoient optionnels dans POSIX (mais pas Unix, et plus dans LSB), ils sont disponibles dans la plupart sinon la totalité des Coquilles de type Bourne que vous rencontrerez probablement jamais).

(BTW, on dirait qu'il /usr/binapparaît deux fois dans votre $PATH, vous pouvez ajouter un typeset -U pathà votre ~/.zshrc)

Stéphane Chazelas
la source
2
Cela a également été soulevé dans une question précédente. Pour étendre ce point, vous devez toujours utiliser une commande intégrée au shell là où elle existe. Donc, en bash, utilisez "type" au lieu de "qui".
Tim B
Excellente réponse et merci pour cette astuce aussi.
nikhil