Dans la plupart des scripts shell que j'ai vus (à part ceux que je n'ai pas écrits moi-même), j'ai remarqué que le shebang est réglé sur #!/bin/sh
. Cela ne me surprend pas vraiment sur les anciens scripts, mais il existe aussi sur des scripts relativement nouveaux.
Y at - il raison de préférer /bin/sh
plus /bin/bash
, depuis bash
est à peu près partout, et souvent par défaut, sur de nombreuses machines Linux et BSD , depuis plus d' une décennie?
/bin/sh
si vous n'utilisez pas debash
fonctions spécifiques . Un jour, vous pourriez être amené à utiliser l'un de vos scripts sur un système sur lequel il n'est pas installé (serveur distant, ordinateur embarqué ...)...the answers so far are fairly subjective...
Un énoncé "subjectif" est essentiellement basé sur une opinion par définition./bin/bash
ne devrait être utilisé que lorsque bash est explicitement requis. En tant que développeur, bien avant 40 ansbash
, je n'en avais presque jamais explicitement eu besoin, sauf lors de tests. (Je m'efforce également d'éviter les extensions de shell, mais la plupart de mes scripts sont destinés à la distribution.) De nombreux scripts sur le net devraient également être destinés à une utilisation étendue.Réponses:
/bin
.la source
/bin/sh
est plus rapide si ce n'est pasbash
, il y a encore quelques systèmes comme OS / X ou RHEL où/bin/sh
estbash
./bin/sh
c'est le cas/bin/bash
. Ubuntu passant de bash à dash les a tous brisés.#!/bin/bash
s'ils voulaient Bash (rien à redire à ça!). Le changement a été principalement effectué en amont dans Debian. Cela a amélioré l'expérience utilisateur et a eu un impact mesurable sur le temps de démarrage du système. Cela a également eu un impact positif sur la sécurité, voir "Shellshock".La plupart des scripts système sous Linux (liés à Debian: Ubuntu, Mint, etc.) sont écrits pour s'exécuter dans le tiret plus rapide, qui est la valeur par défaut / bin / sh sur ces systèmes. La raison est double:
Vitesse du système Un code plus petit de tirets se charge plus rapidement et est également plus rapide. Avec quelques (petits?) Efforts supplémentaires (coûts) pour les programmeurs de scripts shell.
Sécurité. Avoir une diversité de coques aide à la résilience aux bugs. Les systèmes Debian n'étaient généralement pas vulnérables à shellshock car le shell par défaut ne présentait pas une telle vulnérabilité.
Bash est en effet le shell par défaut pour les utilisateurs , car il est plus puissant et contient beaucoup plus d’éléments pour faciliter le codage. C'est également la valeur
sh
par défaut sous Mac OS (celle liée à / bin / sh). Cependant, appelerbash
avec le nom du lien lesh
fait démarrer comme un shell conforme à posix.la source
eval
, avec un risque de sécurité inhérent; de même, sans prise en charge intégrée des expressions rationnelles, il peut être nécessaire d'utiliser des commandes externes (avec une lourde pénalité de performance) pour faire correspondre même sur une seule ligne, etc.D'autres ont souligné que les prémisses de la question, à savoir que le shell Bourne Again est un défaut et omniprésent, sont carrément fausses.
En plus de cela, il existe effectivement de bonnes raisons d'utiliser autre chose que le shell Bourne Again pour interpréter les scripts shell. Ces raisons motivées grand projet de Ubuntu et Debian, sur plusieurs années, pour éliminer bashismes et de faire autant de scripts shell exécutés par l' initialisation du système (qui était beaucoup de scripts shell avec le système 5
rc
) et l' installation de paquets / utilisation de l' élimination de la Le shell Debian Almquist au lieu du shell Bourne Again.Autrement dit, le shell Bourne Again, riche en fonctionnalités interactives, n’est pas l’interpréteur de shell le plus rapide pour un script shell conforme à POSIX. Donc, si on peut créer des scripts shell conformes à POSIX, en les interprétant avec un programme plus léger, comme le shell Debian Almquist, son système fonctionnera mieux. (En fin de compte, Debian a dû apporter de légers ajustements au shell Almquist, pour ajouter un support pour quelques constructions de shell non POSIX qui étaient simplement trop profondes et trop intégrées et trop utiles pour s'en débarrasser.)
Le résultat de tout cela a été un gain majeur en performances de bootstrap.
Donc, il y a deux classes distinctes de shell à considérer, ici:
Notez que parler de cela comme "préférer
/bin/sh
" est une simplification excessive. Debian avait en fait au moins deux objectifs:Face aux administrateurs utilisant le shell Debian Almquist, le shell Z (en mode POSIX), le shell Bourne Again (en mode POSIX), le shell MirBSD Korn, etc.
/bin/sh
, il y avait soit…… Rendre les scripts aussi portables que possible, de sorte que le basculement vers ce qui a été
/bin/sh
mappé ne casse pas les choses; ou… Faire des scripts non portables cibler explicitement le bon programme d'interprétation , au lieu d'attendre simplement cette
/bin/sh
carte.Il y avait fait la Debian Almquist shell le mappage par défaut pour la
/bin/sh
place de la Bourne Shell, de sorte que ces scripts étaient compatible POSIX (ou, plus correctement, Debian Policy Manual conforme) ont couru plus vite.Et bien sûr, une fois que l’on s’y prend, on peut aller beaucoup plus loin; tels que la prise en compte des compromis d'efficacité de ceux qui aiment
/bin/true
et/usr/bin/clear
être des scripts shell ou des programmes compilés. Mais cela dépasse le cadre de cette réponse, heureusement. ☺Rien de tout cela n'est très nouveau, ni même spécifique à Unix, bien sûr. Avant le début du siècle, j’écrivais et publiais un interpréteur de ligne de commande disponible en versions "interactive" et "non-interactive", expliquant cette division même dans son document et notant la différence entre les variables d’environnement
COMSPEC
etOS2_SHELL
. De même, la discussion sur la suppression des basismes dans le System V de Debianrc
et les scripts d'installation / de suppression de paquets remonte aux années 1990.Lectures complémentaires
/bin/sh
. Ubuntu wiki./bin/sh
. Wiki Debian.la source
Schily Bourne Shell
page de manuel, voir schilytools.sourceforge.net/bosh.html sont appropriés pour permettre aux gens de comprendre comment écrire un script portable (cela ne dépend queBourne Shell features
de 1989). Ce que j'ai fait, c'est mentionner toutes les améliorations qui ne sont pas dans les vieux Bourne Shells. BTW: Je suis également intéressé à connaître une liste de bashismes en dash.Oui. @ L'excellente réponse de Marco le décrit bien.
Lorsque vous écrivez vos propres scripts, vous devriez indiquer au shebang la chose la plus générale que vous avez testée.
Sur mon système (Centos 6.6),
sh
est lié symboliquement àbash
:Cela signifie que je l'utilise toujours
#!/bin/bash
dans mon shebang à moins d'avoir vérifié que je n'ai pas de bashims dans mon script.En définissant le shebang sur
#!/bin/sh
vous, vous promettez que le script fonctionnera avec toutes les implémentations desh
.C'est une promesse beaucoup plus grande que de dire que le script fonctionnera avec bash.
Voici un exemple de script qui se comportera de manière incorrecte en fonction de l'
sh
implémentation utilisée par le système:Lors de l'utilisation
bash
du script imprimera:Lors de l'utilisation
dash
du script imprimera:Si je veux utiliser
#!/bin/sh
que dois-je faire?checkbashisms
- Notez que cela ne trouvera pas tous les bashims. Il n'a pas trouvé le bashisme dans mon script ci-dessussh
implémentation. Je teste généralement avecdash
, mais je pense que certains bashismes ou dashims peuvent toujours passer à travers.La page DashAsBinSh sur le wiki Ubuntu contient de nombreuses informations intéressantes.
la source
/bin/sh
; juste ceux compatibles POSIX.La seule raison qui reste pour écrire un script shell, au lieu d'un script dans un langage plus puissant et ergonomique, est si la portabilité vers des systèmes hérités avec un ensemble inconnu de logiciels installés est plus importante que tout autre facteur .
/bin/sh
est le seul et unique interprète de script disponible sur tout ce qui s'appelle Unix. Mais sur un grand nombre de systèmes hérités,/bin/sh
et les utilitaires associés ne sont même pas conformes à la spécification "shell and utilities" de POSIX.1-1996, sans parler de quelque chose de plus moderne. Les outils conformes aux normes sont un complément optionnel, installé dans/usr/xpg4
ou dans un tel lieu non évident. 1 La génération de scripts dans le langage shell de sous-ensembles portable est encore plus fastidieuse et sujette aux erreurs que celle de scripts dans le langage shell POSIX. (Lisez unconfigure
script généré par Autoconf si vous ne me croyez pas. La configuration devrait suffire à vous convaincre.)Mais si vous pouvez supposer qu'un autre interpréteur de script est installé (par exemple, Bash), vous pouvez alors supposer qu'un interprète est installé pour un meilleur langage de script . Perl, par exemple, a plus de chances d’être disponible que Bash.
Par conséquent, vous ne devriez jamais écrire de
#! /bin/bash
script, car si c'est une option, une meilleure langue est également une option.1 Par exemple, Solaris 10 et versions antérieures ont fourni le shell Bourne d'origine en tant que
/bin/sh
. Je suis informé que Solaris 11 l'a mis à jour vers ksh93.la source
/bin/sh
n'est pas un shell Bourne original de syntaxe antérieure à POSIX. Cela fait#!/bin/sh
un très mauvais shebang pour les scripts à exécuter avec ces versions. Les scripts portables sur Solaris utiliseraient,#!/usr/xpg4/bin/sh
ce qui ne sera pas très portable sur d'autres systèmes d'exploitation. Sur la dernière version de Solaris, Oracle Solaris 11, première version 2011,/bin/sh
est un système moderneksh93
conforme aux spécifications POSIX les plus récentes et doté de nombreuses extensions modernes.ash
qui sont fournis avec busybox), et j’ai tendance à penser que zwol a raison de dire que perl est plus communément disponible que bash.bash
est disponible, le langage est meilleur, vous ne devriez donc jamais écrire debash
code." En outre, comme le fait remarquer @sixtyfootersdude, vous devez toujours utiliser#!/bin/bash
sauf si vous avez vérifié que votre script fonctionne avec n'importe quel shell POSIX.Vous devriez réellement utiliser soit
ou
De cette façon, vous appelez l’un ou l’autre shell par la manière dont ils sont installés sur ce système.
Pour être très sûr ( par exemple, en cas de redémarrage par un utilisateur unique), utilisez
sh
sinonbash
.la source
the advantage of #!/usr/bin/env python is that it will use whatever python executable appears first in the user's $PATH. The disadvantage of #!/usr/bin/env python is that it will use whatever python executable appears first in the user's $PATH.
Cela s'applique probablement aussi àsh
etbash
.#!/bin/env
dans un script portable. Il est parfaitement raisonnable de supposer qu’il/bin/sh
existe un shell fonctionnant conformément à POSIX. D'autre part, aucun de mes systèmes n'a un/bin/env
./bin/sh
. POSIX n'en a pas besoin et définit plutôt d'autres règles pour obtenir un environnement compatible POSIX sur une plate-forme certifiée POSIX./usr/bin/env
pas universellement disponible ...