web-dev-qa-db-fra.com

Pourquoi y a-t-il un / bin / echo et pourquoi voudrais-je l'utiliser?

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?

51
Zanna

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:

  1. Vous n'utilisez pas toujours un Shell. Dans diverses circonstances, vous exécutez un exécutable directement et non via un shell.
  2. Au moins en théorie, certains coquillages n’ont pas de 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
87
Eliah Kagan

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?

30
muru