Lorsque sh est un lien symbolique vers bash ou dash, bash se limite à la conformité POSIX, il devrait donc être 100% compatible avec sh?

8

De la différence entre bash et sh :

ABck à la question: Si vous avez /bin/shun lien vers bash, alors bash ne se comportera pas de la même manière lorsqu'il est appelé /bin/shcomme il le fait lorsqu'il est appelé comme /bin/bash. Lorsqu'il est appelé en tant que sh, il se limitera principalement à la conformité POSIX plus un ensemble limité d'extensions.

Est-ce que cela signifie que chaque fois que je rencontre un script shell sous Linux avec un shebang to sh:, #!/bin/shmême si sur cette distribution, bin/shc'est un lien symbolique vers un autre shell, comme dash ou bash, il devrait être 100% compatible avec le bourne shell, car se limite-t-elle à un ensemble limité d'extension? Je pourrais donc les exécuter dans FreeBSD? Y a-t-il une exception à cela? Ou devrais-je être sûr de supposer que cela fonctionnera?

Donc, si sur une distribution, bin/shest un lien symbolique vers bin/bash, et un script utilise #!/bin/shet le script contient bashism, il ne fonctionnera pas, car bash aimera être en mode sh?

user1115057
la source

Réponses:

16

Non, si /bin/shun lien symbolique vers bash bash entre en mode posix - de man bash :

Lorsqu'il est appelé en tant que sh, bash entre en mode posix après la lecture des fichiers de démarrage.

Si vous recherchez maintenant le mode posix sur la page de manuel bash, vous verrez que certaines commandes internes du shell aiment timeou sourcese comportent différemment. C'est tout. les bashishms comme écrire functionavant de déclarer une fonction ou utiliser sourceau lieu de .still fonctionneront mais les commandes peuvent se comporter différemment.

Donc, si /bin/shun lien symbolique vers /bin/bashtous les bashishms typiques fonctionne toujours.

Pour une liste assez complète des différences dans le mode Posix, consultez le manuel de référence bash .

Ulrich Dangel
la source
Je suppose donc que la meilleure chose à faire est de tester tous les scripts dans l'outil checkbashism. J'ai entendu dire que certaines distributions, comme Debian et Ubuntu (besoin d'une confirmation pour celui-ci) avaient leur lien symbolique bin / sh à dash. Dash est-il compatible avec le shell bourn? Si oui, alors au moins tous les scripts shell Debian et Ubuntu devraient être corrects sous FreeBSD.
user1115057
@ user1115057 uniquement les scripts shell avec /bin/shcomme shebang. Un script shell peut toujours utiliser explicitement /bin/bash. Quoi qu'il en soit, la plupart des scripts shell fonctionneront probablement bien sous / bin / sh mais le problème sera les outils utilisateur, par exemple la plupart des scripts shell attendent GNU userland qui sera probablement plus un problème qu'une simple erreur de syntaxe. J'ai également ajouté un lien vers la référence bash qui répertorie les différents comportements en mode posix
Ulrich Dangel
Ok d'après ce que j'ai lu, BSD utilise ash comme bin / sh, tandis que Debian et Ubuntu utilisent dash. Si ces shell sont compatibles, cela signifie que je n'aurai plus de problème avec shebang #! / Bin / sh. Mais comme vous l'avez dit, il y aura un autre problème lié à l'
espace
@ user1115057 dash n'est pas non plus parfait, par exemple wiki.ubuntu.com/DashAsBinSh/#echo de toute façon la plupart des scripts shell sont plutôt simples et peuvent être portés assez facilement… bonne chance
Ulrich Dangel
Mais le tableau de bord et le frêne sont compatibles non?
user1115057
8

Il semble y avoir une certaine confusion autour du shell Bourne. Le shell Bourne était un shell Unix il y a des décennies, à l'époque pré-POSIX. De nos jours, "sh" est une implémentation ou une autre d'un shell qui implémente la spécification POSIX, parmi lesquels nous avons bash, pdksh, AT&T ksh, les plus récents shells Almquist et leurs dérivés qui ont été rendus conformes POSIX (y compris le "sh" de certains BSD) , d'autres BSD sh étant basés sur pdksh et Debian ash (tiret)). Même zsh a un mode dans lequel il est principalement conforme à POSIX.

Le shell Bourne n'est pas compatible POSIX et ne peut pas être trouvé sur de nombreux systèmes de nos jours. Où le shell Bourne est trouvé ou où il ne l'est pas, il y aura toujours un "sh" qui est compatible POSIX (et ne sera pas le shell Bourne), généralement /binpendant qu'une exception notable (ennuyeuse) est Solaris.

Notez qu'avant le Bourne shell, et nous parlons il y a plus de 30 ans, "sh" était le Thompson shell. Nous n'écrivons plus de scripts compatibles avec le shell Thompson. De même, nous devons arrêter de penser à "sh" comme le shell Bourne.

Maintenant "sh" est une spécification, pas beaucoup de variantes parfois incompatibles d'une implémentation. Cela facilite grandement l'écriture de scripts portables. Suivez simplement les spécifications .

Cela vaut pour "sh" et tous les utilitaires standards (sed, cut, tr ...)

Stéphane Chazelas
la source
+1 pour "écrire dans la spécification". Mais malheureusement, ce n'est souvent pas suffisant pour la portabilité. Par exemple, que faire si l'on veut utiliser des motifs de style egrep dans sed? La spécification ne le prévoit pas. Sur les systèmes avec des utilitaires basés sur Gnu (ou BusyBox), vous utilisez sed -r. Sur les systèmes avec des utilitaires basés sur BSD, vous utilisez sed -E. Sed de FreeBSD accepte les deux, mais Mac OS X seulement accepte -E. Ainsi de suite.
dubiousjim
C'est à côté du point. La spécification ne le fournit pas, vous ne pouvez donc pas l'utiliser de manière portable / POSIXly. Si vous utilisez des BRE, cela fonctionnera sur tous les systèmes conformes POSIX, c'est une garantie donnée par POSIX, c'est pourquoi c'est utile. En dehors de POSIX comme vous le dites, il n'y a aucun espoir car seds ne prend pas en charge ERE ou le prend en charge avec une option ou une syntaxe ERE différente. Notez que les ERE sont moins capables que les BRE (seule la syntaxe est étendue dans les ERE pour vous éviter de taper. Les ERE peuvent être traduits en BRE, le contraire n'est pas vrai (les BRE \(...\)\1n'ont pas de traduction dans les ERE standard).
Stéphane Chazelas
1
Je me rends compte que les ERE (POSIX) manquent de références; en fait, j'ai participé à l'édition de cette partie de la norme. Il n'est pas correct que les ERE POSIX soient strictement moins capables que les BRE, car dans la norme actuelle, l'alternance n'est pas définie pour les BRE. Cependant, je ne connais aucun moteur de regex qui n'honore pas les \|BRE. Je suis pour l'écriture la plus portable possible. Je ne faisais que l'observation (je pensais largement appréciée) que cela peut être douloureux, et parfois écrire à POSIX n'est tout simplement pas possible. Quelque part ont des liens qui présentent beaucoup de telles perversions; va les chercher.
dubiousjim
bon point sur l'alternance, j'ai oublié cela et restez corrigé. Avec sed, il est peu probable qu'il bloque, car vous pouvez utiliser plusieurs expressions pour faire correspondre les expressions rationnelles alternatives. Il y a un awk dans le toolchest standard qui peut être utilisé si des ERE sont nécessaires. Je me retrouve très rarement par le toolchest standard, et quand je le fais, c'est généralement des cas où une autre langue comme perl est plus appropriée, mais je vois votre point (bien que je pense toujours que ce n'est pas le point dans ce fil sur l'écriture de scripts portables)
Stéphane Chazelas
Un exemple auquel j'ai pensé par inadvertance: les lignes de shebang (en haut de chaque script shell) ne sont pas spécifiées dans POSIX. De plus, je ne suis pas sûr d'avoir déjà utilisé un système 100% compatible POSIX. Par exemple, POSIX dit que vous pouvez inclure des sauts de ligne à l'intérieur ${VAR:=stuff...here}mais que de nombreux shells ne vous le permettent pas, vous devez mettre des guillemets stuff...here.
dubiousjim