Vous l'avez en arrière. /bin/shn'est presque jamais une coquille Bourne de nos jours, et c'est quand c'est¹ que vous avez un problème lorsque vous utilisez une #! /bin/shshe-bang.
Le obus Bourne était un obus écrit à la fin des années 70 et a remplacé le précédent obus Thompson (également appelé sh). Au début des années 80, David Korn a écrit quelques extensions pour le shell Bourne, corrigé quelques bugs et conçu des maladresses (et en a introduit) et l'a appelé le shell Korn.
Au début des années 90, POSIX a spécifié le sh langage basé sur un sous-ensemble du shell Korn et la plupart des systèmes¹ ont désormais changé /bin/shpour le shell Korn ou un shell conforme à cette spécification. Dans le cas des BSD, ils ont progressivement changé leur /bin/sh, initialement (après qu'ils ne pouvaient plus utiliser le shell Bourne pour des raisons de licence) le shell Almquist, un clone du shell Bourne avec quelques extensions ksh donc il est devenu conforme POSIX.
Aujourd'hui, tous les systèmes POSIX ont un shell appelé sh(le plus souvent, mais pas nécessairement dans /bin, POSIX ne spécifie pas le chemin des utilitaires qu'il spécifie) qui est principalement conforme à POSIX. Il est généralement basé sur ksh88, ksh93, pdksh, bash, ash ou zsh², mais pas sur le shell Bourne car le shell Bourne n'a jamais été conforme POSIX³. Quelques - unes de ces coquilles ( bash, zsh, yashet certains pdkshdérivés permettent un mode compatible POSIX lorsqu'il est invoqué comme shet sont moins conformes par ailleurs).
bash(la réponse GNU au shell Korn) est en fait le seul shell open source (et on pourrait dire seulement actuellement maintenu car les autres sont généralement basés sur ksh88 qui n'a obtenu aucune nouvelle fonctionnalité depuis les années 90) qui a été certifié comme être conforme à POSIX sh(dans le cadre de la certification macOS).
Lorsque vous écrivez un script avec un #! /bin/sh -she-bang, vous devez utiliser une shsyntaxe standard (et également utiliser la syntaxe standard pour les utilitaires utilisés dans ce script si vous voulez être portable, ce n'est pas seulement le shell qui est impliqué lors de l'interprétation d'un shell script), peu importe l'implémentation de cet shinterpréteur de syntaxe standard utilisée ( ksh, bash...).
Peu importe que ces shells aient des extensions par rapport à la norme tant que vous ne les utilisez pas. C'est comme pour écrire du code C, tant que vous écrivez du code C standard et que vous n'utilisez pas d'extensions d'un compilateur (comme gcc) ou de l'autre, votre code devrait compiler OK quelle que soit l'implémentation du compilateur à condition que le compilateur soit conforme.
Ici, avec votre #! /bin/shelle-bang, votre principal problème serait les systèmes où /bin/shest le shell Bourne que par exemple ne prend pas en charge des fonctionnalités standard comme $((1+1)), $(cmd), ${var#pattern}... Dans ce cas , vous devrez peut - être contournements comme:
#! /bin/sh -
if false ^ true; then
# in the Bourne shell, ^ is an alias for |, so false ^ true returns
# true in the Bourne shell and the Bourne shell only.
# Assume the system is Solaris 10 (older versions are no longer maintained)
# You would need to adapt if you need to support some other system
# where /bin/sh is the Bourne shell.
# We also need to fix $PATH as the other utilities in /bin are
# also ancient and not POSIX compatible.
PATH=`/usr/xpg6/bin/getconf PATH`${PATH:+:}$PATH || exit
export PATH
exec /usr/xpg4/bin/sh "$0" "$@"
# that should give us an environment that is mostly compliant
# to the Single UNIX Specification version 3 (POSIX.2004), the
# latest supported by Solaris 10.
fi
# rest of the script
Par ailleurs, Ubuntu /bin/shn'est pas bashpar défaut. C'est de dashnos jours, un shell basé sur NetBSD sh, lui-même basé sur le shell Almquist qui est principalement compatible POSIX, sauf qu'il ne prend pas en charge les caractères multi-octets. Sur Ubuntu et d'autres systèmes basés sur Debian, vous pouvez choisir entre bashet dashpour /bin/shavec dpkg-reconfigure dash) 4 . shles scripts fournis avec Debian devraient fonctionner de la même manière dans les deux shells car ils sont écrits dans le standard de politique Debian (un surensemble du standard POSIX). Vous constaterez probablement qu'ils fonctionnent aussi bien dans zshl' shémulation de bosh( ou probablement pas ksh93et yashqui n'ont pas de fonction localintégrée (requis par la politique Debian mais pas POSIX)).
Tous les systèmes concernés par unix.stackexchange.com ont un POSIX sh quelque part. La plupart d'entre eux ont un /bin/sh(vous pouvez en trouver de très rares qui n'ont pas de /binrépertoire mais vous ne vous en souciez probablement pas), et c'est généralement un shinterpréteur POSIX (et dans de rares cas un shell Bourne (non standard) à la place ).
Mais shc'est le seul exécutable interpréteur de shell que vous pouvez être sûr de trouver sur un système. Pour les autres shells, vous pouvez être sûr que macOS, Cygwin et la plupart des distributions GNU / Linux auront bash. Les systèmes d'exploitation dérivés de SYSV (Solaris, AIX ...) auront généralement ksh88, éventuellement ksh93. OpenBSD, MirOS aura un dérivé pdksh. macOS aura zsh. Mais hors de cela, il n'y aura aucune garantie. Aucune garantie que ce soit bashou l'un de ces autres shells sera installé dans /binou ailleurs (il se trouve généralement dans /usr/local/binles BSD lors de l'installation par exemple). Et bien sûr aucune garantie de la version du shell qui sera installée.
Notez que ce #! /path/to/executablen'est pas une convention , c'est une fonctionnalité de tous les noyaux de type Unix ( introduite au début des années 80 par Dennis Ritchie ) qui permet d'exécuter des fichiers arbitraires en spécifiant le chemin de l'interpréteur dans une première ligne commençant par #!. Il peut s'agir de n'importe quel exécutable.
Lorsque vous exécutez un fichier dont la première ligne commence par #! /some/file some-optional-arg, le noyau finit par s'exécuter /some/fileavec some-optional-arg, le chemin du script et les arguments d'origine comme arguments. Vous pouvez faire cette première ligne #! /bin/echo testpour voir ce qui se passe:
$ ./myscript foo
test ./myscript foo
Lorsque vous utilisez à la /bin/sh -place de /bin/echo test, le noyau s'exécute /bin/sh - ./myscript foo, shinterprète le code de contenu stocké dans myscriptet ignore cette première ligne car il s'agit d'un commentaire (commence par #).
¹ Probablement le seul système aujourd'hui où l'un de nous rencontrera un /bin/shqui est basé sur le shell Bourne est Solaris 10. Solaris est l'un des rares Unices qui a décidé de garder un shell Bourne là pour la compatibilité descendante (le shlangage POSIX n'est pas complètement rétrocompatible avec le shell Bourne) et (au moins pour les déploiements de bureau et de serveur complet) ont le POSIX shailleurs (dans /usr/xpg4/bin/sh, basé sur ksh88), mais cela a changé dans Solaris 11 où /bin/shest maintenant ksh93. Les autres sont pour la plupart disparus.
² Le /bin/shMacOS / X était autrefoiszsh , mais plus tard changé en bash. Ce n'est pas zshl'objectif principal d'être utilisé comme une shimplémentation POSIX . Son shmode est avant tout de pouvoir embarquer ou appeler ( source) du shcode POSIX dans des zshscripts
³ Récemment, @schily a étendu le shell OpenSolaris (basé sur le shell SVR4, basé sur le shell Bourne) pour devenir compatible POSIX, appelé boshmais je ne suis pas au courant qu'il soit utilisé sur aucun système pour le moment. Avec ksh88ce fait un deuxième coque compatible POSIX basé sur le code de la coque Bourne
4 Dans les anciennes versions, vous pouviez également utiliser mkshou son lkshincarnation plus POSIX . C'est le shell MirOS (anciennement MirBSD) basé sur pdksh, lui-même basé sur le shell Forsyth (une autre réimplémentation du shell Bourne))