web-dev-qa-db-fra.com

Quel est le problème avec les Bashism?

Par "Bashism", je veux dire une syntaxe de shell qui est uniquement comprise par le shell bash et non par d’autres shell.

Si vous écrivez un script qui est exécuté uniquement dans des environnements où /bin/bash existe, je pense qu'éviter le bashisme est simplement inutile et fait perdre du temps, mais peut-être qu'il me manque quelque chose.

Quel est l’avantage de créer des scripts de manière plus compliquée, quand il existe une solution plus facile si vous êtes autorisé à utiliser une fonctionnalité qui est uniquement disponible dans Bash?

Il y a une question complémentaire: Existe-t-il des chiffres concrets sur la vitesse de bash par rapport à dash?

J'ai publié ma conclusion ici: https://github.com/guettli/programming-guidelines/blob/master/README.rst#portable-Shell-scripts

4
guettli

Tout d'abord, la portabilité. Rien à redire si vous êtes sûr que la version bash (et de préférence identique ou plus récente) sera disponible partout où vous utilisez le script. Si vous êtes un développeur ou un administrateur système qui s'attend à ce qu'un logiciel soit utilisé sur un système d'exploitation de type Unix en dehors d'Ubuntu et qu'ils aient ou non bashname__, les bashismes ne seront pas compris par /bin/sh.

Deuxièmement, la conformité à POSIX. Si vous écrivez et soumettez des scripts à inclure dans le système d’exploitation ou dans un projet, ils doivent souvent utiliser la syntaxe /bin/sh, qui correspond en gros à la norme POSIX. /bin/sh est souvent préféré pour des raisons de performances, donc si vous avez besoin de rapidité dans les scripts Shell, bashismes et donc bash peut-être quelque chose à éviter.

En bref, les bashismes ne sont pas mauvais. Cela dépend vraiment du contexte dans lequel vous écrivez un script. S'il est certain que bash sera disponible et qu'il ne sera pas très obsolète, tous les utilisateurs utiliseront les fonctionnalités - elles sont là pour une raison.

11
Sergiy Kolodyazhnyy

Rien, en tant que tel, si vous savez que vous utilisez une fonctionnalité spécifique à Bash, et n'oubliez pas d'utiliser le hashbang #!/bin/bash au lieu de supposer que /bin/sh est Bash.

Dans Ubuntu (et Debian), les "bashismes" dans #!/bin/sh sont principalement un problème lorsque le /bin/sh par défaut a été remplacé par Dash au lieu de Bash (voir DashAsBinSh dans le wiki Ubunt ). Tous les scripts exécutés avec /bin/sh devaient être vérifiés pour les bashismes et corrigés pour utiliser les fonctionnalités standard prises en charge par Dash. Le changement ne concernait pas la disponibilité de Bash (il s'agit toujours d'un paquet Essential, donc toujours installé), mais de la rapidité: avant systemd, le processus de démarrage générait de nombreux scripts Shell et la modification rapide du shell par défaut avait réellement un impact.

Sur d'autres systèmes, /bin/sh peut toujours être Bash, ce qui permet d'utiliser accidentellement des fonctionnalités spécifiques à Bash dans les scripts marqués avec #!/bin/sh. Ils ne fonctionneraient pas directement dans un système où sh n'est pas Bash. Ensuite, il y a des systèmes qui n'ont pas du tout Bash. Les systèmes embarqués n’ont souvent que le Busybox Shell. Unixen non-Linux n'a peut-être pas Bash, bien qu'ils aient souvent une version de ksh, d'où proviennent nombre des fonctionnalités de Bash. Ils ne sont pas compatibles 1: 1, cependant.

Certaines des fonctionnalités non standard de Bash sont très utiles (par exemple, des tableaux , des sous-tranches (${var:n:m}), du texte de remplacement ( ${var/foo/bar})), donc s'ils facilitent l'écriture de votre script, utilisez Bash.

Cela dit, certains bashismes ont des équivalents directs standards, ce qui signifie qu'il y a peu de raisons d'utiliser la variante non standard. Certains qui me viennent à l'esprit:

  • l'opérateur == dans [ .. ] est non standard, mais équivalent à l'opérateur standard =
  • function f { ... } et f() { ... } sont équivalents dans Bash, mais le premier n'est pas standard. (Il vient de ksh, où il y a une différence.)
  • $((--n)) n'est pas standard, mais peut être remplacé par $((n=n-1))
  • Dans les cas simples, [[ ... ]] peut être remplacé par le standard [ .. ]
6
ilkkachu