Quelle est la différence entre #! / Bin / sh et #! / Bin / bash?

281

si j'écris,

#!/bin/bash
echo "foo"

ou

#!/bin/sh
echo "foo"

les deux donne le même. J'ai vu des scripts commençant par #!/bin/shou #!/bin/bash. Y a-t-il une différence entre eux?

Rahul Virpara
la source

Réponses:

242

bashet shsont deux coquilles différentes. Au fond bashest sh, avec plus de fonctionnalités et une meilleure syntaxe. La plupart des commandes fonctionnent de la même manière, mais elles sont différentes.

Cela dit, vous devez savoir que la /bin/shplupart des systèmes constitueront un lien symbolique et ne seront pas invoqués sh. Dans Ubuntu, l' /bin/shhabitude de se lier à bash, comportement typique sur les distributions Linux, mais a maintenant changé pour lier à un autre shell appelé dash . Je voudrais utiliser bash, car c'est à peu près la norme (ou du moins la plus commune, de mon expérience). En fait, des problèmes surviennent lorsqu'un script bash doit être utilisé, #!/bin/shcar le créateur de script suppose que le lien est créé bashlorsqu'il n'est pas nécessaire de l'être.

Pour plus d'informations, http://man.cx/sh , http://man.cx/bash .

reverendj1
la source
25
Votre premier paragraphe est assez trompeur. "sh" n'est pas du tout un shell, mais un lien symbolique vers le shell du système actuellement configuré , qui sur les systèmes Linux est généralement bash ou dash (versions récentes d'Ubuntu utilisant ce dernier).
thomasrutter
19
/bin/shétait un shell appelé bourne shell en 1977. bash est un shell compatible / bin / sh qui peut être utilisé comme remplacement de shell bourne qui est conforme à la posix. en.wikipedia.org/wiki/Bourne_shell
Alex
5
bash est un standard de facto (très largement utilisé) mais ce n'est pas un "standard"; sh on Ubuntu utilise dash , qui est un shell compatible Posix, donc il est vraiment standard. Mon conseil est d'utiliser dash aussi souvent que possible pour les scripts, en particulier pour les scripts côté serveur. Bien que bash soit plus expressif, dash est beaucoup plus rapide et plus sécurisé.
Rick-777
@ Rick-777 Alors, devrais-je explicitement mettre #! / Bin / dash en haut de mes scripts? J'ai également écrit des scripts où je n'écris que des commandes et que j'exécute avec ./scriptName et cela a bien fonctionné. Le #! / Bin / yourShellHere est-il nécessaire?
user137717
@ Rick-777 Dans les cas où j'exclus tout #! / Bin / shellName, j'ai nommé les fichiers nomFichier.sh. Cela reliera-t-il implicitement au shell système préféré sans déclarer #! / Bin / sh?
user137717
82

Sous Linux et d’autres systèmes de type Unix, vous avez le choix entre plusieurs shells.

Le shell est responsable non seulement du dessin de votre petite invite, mais également de l’interprétation de vos commandes, en particulier si vous utilisez une logique compliquée, telle que les tubes, les conditions, etc.

bash est le shell le plus couramment utilisé comme shell par défaut pour les utilisateurs de systèmes Linux. C'est un descendant spirituel d'autres coquillages utilisés tout au long de l'histoire d'Unix. Son nom, bash, est l'abréviation de Bourne-Again Shell, un hommage au shell Bourne qu'il a été conçu pour remplacer, bien qu'il incorpore également des fonctionnalités des shell C et Korn.

Il est exécuté, de nos jours, de /bin/bash- tout système avec bash l'aura accessible ici.

Cependant, ce ne sont pas seulement les utilisateurs qui utilisent des coques. Les scripts ( scripts shell ) ont besoin de shells pour les interpréter. Lorsque vous exécutez un script shell, votre système doit démarrer un processus shell pour exécuter votre script.

Le problème, c’est que différents coquillages ont de minuscules incohérences entre eux et qu’il s’agit d’exécuter des scripts, ils peuvent poser un réel problème. bash a beaucoup de fonctionnalités de script qui sont uniques à bash, et non aux autres shells. C'est bien, si vous allez toujours utiliser bash pour exécuter ces scripts. D'autres shells peuvent essayer d'émuler bash ou adhérer au standard POSIX, que bash supporte plutôt bien (bien que ses propres extensions lui soient ajoutées).

Il est possible de spécifier en haut d'un script shell le shell avec lequel il doit être exécuté à l'aide d'un shebang. Un script peut spécifier #!/bin/bashsur la première ligne, ce qui signifie qu'il doit toujours être exécuté avec bash, plutôt qu'avec un autre shell.

/ bin / sh est un exécutable représentant le shell du système . En réalité, il est généralement implémenté sous forme de lien symbolique pointant sur l'exécutable, quel que soit le shell utilisé. Le shell système est un peu le shell par défaut que les scripts système devraient utiliser. Dans les distributions Linux, pendant longtemps, il s'agissait généralement d'un lien symbolique vers bash , à tel point qu'il est devenu en quelque sorte une convention de toujours relier / bin / sh à bash ou à un shell compatible avec bash. Cependant, ces deux dernières années, Debian (et Ubuntu) ont décidé de passer du shell système de bash à dash- un shell similaire - rompant avec une longue tradition sous Linux (bien GNU) d’utiliser bash pour / bin / sh. Dash est considéré comme un shell plus léger et beaucoup plus rapide, ce qui peut être bénéfique pour la vitesse de démarrage (et d’autres tâches nécessitant beaucoup de scripts shell, comme les scripts d’installation de paquet).

Dash est assez bien compatible avec bash, étant basé sur le même standard POSIX. Cependant, il n'implémente pas les extensions spécifiques à bash. Il existe des scripts qui utilisent #!/bin/sh(le shell système) comme shebang, mais qui nécessitent des extensions spécifiques à bash. Ceci est actuellement considéré comme un bogue qui devrait être corrigé par Debian et Ubuntu, qui ont besoin que / bin / sh soit capable de travailler lorsque pointé vers tiret.

Bien que le shell système d'Ubuntu pointe vers le tiret, votre shell de connexion en tant qu'utilisateur continue d'être bash pour le moment. Autrement dit, lorsque vous vous connectez à un émulateur de terminal où que vous soyez sous Linux, votre shell de connexion sera bash. La vitesse de fonctionnement n'est pas vraiment un problème lorsque le shell est utilisé de manière interactive et que les utilisateurs sont familiarisés avec bash (et peuvent avoir des personnalisations spécifiques à bash dans leur répertoire de base).

Ce que vous devez utiliser lorsque vous écrivez des scripts

Si votre script nécessite uniquement des fonctionnalités prises en charge par bash, utilisez #!/bin/bash.

Mais dans la mesure du possible, il serait bon de vous assurer que votre script est compatible POSIX, et utilisez-le #!/bin/sh, qui devrait toujours, de manière assez fiable, pointer sur le shell système compatible POSIX préféré dans toute installation.

thomasrutter
la source
18

En plus des réponses précédentes, même si /bin/shest un lien symbolique vers /bin/bash, #!/bin/shn’est pas totalement équivalent à #!/bin/bash.

De la page de manuel bash (1) :

"Si bash est appelé avec le nom sh, il essaie de reproduire le plus fidèlement possible le comportement au démarrage des versions historiques de sh, tout en se conformant également au standard POSIX."

Par exemple, la syntaxe spécifique à bash:

 exec  > >(tee logfile.txt)

donne une erreur dans un shell commençant par #!/bin/sh, même avec le lien symbolique sh-> bash en place.

AnkiF
la source
6

GNU Bash: #!/bin/bash; POSIX: #!/bin/sh.

茶树 和 葡萄 树
la source
Eh bien, réponse courte mais précise. 行
Sergiy Kolodyazhnyy