J'ai remarqué qu'il y a un exécutable binaire /bin/echo
sur mon système Ubuntu MATE 17.04.
J'ai pensé, c'est étrange, parce que
$ type echo
echo is a Shell builtin
Des tests poussés suggèrent que /bin/echo
fait le même genre de chose que le Bash intégré à echo
:
$ /bin/echo foo
foo
$ /bin/echo $USER
zanna
Alors, pourquoi existe-t-il une autre version de echo
distincte du programme Bash, et pourquoi ou quand voudrais-je l’utiliser?
Si vous ouvrez une invite bash
et tapez une commande echo
, celle-ci utilise un Shell intégré plutôt que d'exécuter /bin/echo
. Les raisons pour lesquelles /bin/echo
existe toujours sont les suivantes:
echo
intégré. Ce n'est pas réellement nécessaire.Pour développer le n ° 1, supposons que vous vouliez déplacer tous les fichiers normaux dont le nom commençait par abc
n'importe où dans src
vers dest
. Il y a plusieurs façons de le faire, mais l'une d'entre elles est:
find src -name 'abc*' -type f -exec mv -nv {} dest/ \;
Mais supposons plutôt que de simplement exécuter cela, vous voulez voir chaque commande qui sera exécutée en premier. Eh bien, vous pouvez alors ajouter echo
à la commande, comme dans d’autres contextes:
find src -name 'abc*' -type f -exec echo mv -nv {} dest/ \;
Mais find
n'utilise pas de shell. Cela fonctionne /bin/echo
.
Outre find
avec -exec
OU -execdir
, l'exécutable /bin/echo
sera appelé par d'autres programmes qui exécutent eux-mêmes des programmes, mais pas via un shell. Ceci se produit avec la commande xargs
(qui est lié à find
), ainsi que dans un certain nombre d'autres contextes, tels que la ligne Exec=
de n fichier .desktop
. Un autre exemple est lorsque vous exécutez Sudo echo
, ce qui peut être utile pour tester si Sudo
fonctionne.
De même, certains shells ont un printf
intégré mais /usr/bin/printf
existe aussi.
Une raison moins courante que vous pourriez utiliser délibérément /bin/echo
est si vous vous basez sur les différences entre celui-ci et la commande echo
fournie par votre shell. man echo
documents /bin/echo
; help echo
DANS bash
documente le bash
intégré. echo
n’est pas très portable, car différentes implémentations - d’un système d’exploitation à l’autre et d’un shell à l’autre sur le même système d’exploitation -- prennent en charge différentes options (par exemple, -e
) et diffèrent dans leur traitement des barres obliques inversées . Bien sûr, il vaut mieux éviter de s’appuyer sur de tels détails et utiliser plutôt printf
, qui est beaucoup plus portable .
Dans bash
, vous pouvez également créer l'affichage type
intégré /bin/echo
- en supposant que /bin
se trouve dans votre $PATH
comme il se doit toujours - by en lui passant le drapeau -a
:
$ type -a echo
echo is a Shell builtin
echo is /bin/echo
Eliah a très bien répondu à cette question, mais je tiens à commenter la partie "pourquoi existe-t-il une autre version de echo
distincte du programme Bash"? C'est la mauvaise question.
La bonne question est la suivante: pourquoi s’agit-il d’une commande intégrée en premier lie , alors qu’elle aurait pu être (et est) une commande externe parfaitement fine?
Pour plus de simplicité, jetez un coup d’œil aux commandes intégrées dans dash, un maigre 38 (bash en a 61, à titre de comparaison, en se basant sur le résultat de compgen -b
):
. continue getopts readonly type
: echo hash return ulimit
[ eval jobs set umask
alias exec kill shift unalias
bg exit local test unset
break export printf times wait
cd false pwd trap
command fg read true
Combien de ces doivent être intégrés? [
, echo
, false
, printf
, pwd
, test
et true
n'a pas besoin être intégré: ils ne font rien que seul un intégré peut faire (affecter ou obtenir Etat du shell non disponible pour les commandes externes). printf
de Bash tire au moins avantage d'être intégré: printf -v var
enregistre la sortie dans la variable var
. time
dans bash est également spécial: en étant un mot clé, vous pouvez chronométrer des listes de commandes arbitraires dans bash (dash n'a pas d'équivalent time
). pwd
n'a pas non plus besoin d'être intégré - toute commande externe héritera du répertoire de travail actuel (et il s'agit également d'une commande externe ). :
est une exception - vous avez besoin d'un NOP, et :
l'est. Les autres font des actions qu'une commande externe peut facilement faire.
Ainsi, un cinquième de ces tâches intégrées n'a pas besoin d'être intégré. Pourquoi alors? La page de manuel dash
* explique, en passant, pourquoi ils sont intégrés (emphase moi):
Builtins Cette section répertorie les commandes intégrées qui sont intégrées car elles Doivent exécuter certaines opérations qui ne peuvent pas être exécutées par un processus séparé . En plus de celles-ci, , il existe plusieurs autres commandes pouvant Être intégrées pour plus d'efficacité (par exemple, printf (1), echo (1) , test (1), etc.).
C'est à peu près tout: ces éléments intégrés existent parce qu'ils sont utilisés très souvent, de manière interactive et dans des scripts, et que leurs fonctionnalités sont suffisamment simples pour que le shell puisse faire le travail. Et c’est ce qui se produit: certains (la plupart?) Obus ont pris le travail. ** Retournez à le sh
à partir de 2.9 BSD , et vous ne trouverez pas de echo
intégré. .
Donc, il est tout à fait possible qu'un shell minimal puisse ignorer l'implémentation de telles commandes en tant que commandes intégrées (je ne pense pas que ce soit le cas de tous les Shell actuels). Le projet GNU coreutils ne suppose pas que vous allez les exécuter dans un shell particulier, et POSIX requiert ces commandes. Ainsi, coreutils les fournit quand même et ignore ceux qui n’ont aucune signification en dehors de Shell.
* Ceci est presque identique à le texte de page de manuel correspondant pour le shell Almquist , sur lequel est basé dash, le shell Debian Almquist.
** zsh
pousse cette idée à l'extrême: les commandes que vous obtenez en chargeant différents modules, comme zmv
, sont des choses que vous ne penseriez pas qu'un Shell devrait même entrer dans . A ce stade, la vraie question est: pourquoi voudriez-vous utiliser bash au lieu de zsh, qui possède toutes ces fonctions intégrées?