it-swarm.com.de

Was ist das Problem mit Bashisms?

Mit "Bashism" meine ich die Shell-Syntax, die nur von der Bash-Shell und nicht von anderen Shells verstanden wird.

Wenn Sie ein Skript schreiben, das nur in Umgebungen ausgeführt wird, in denen /bin/bash existiert, dann halte ich das Vermeiden von Bashismus für nutzlos und zeitraubend, aber vielleicht fehlt mir etwas.

Was bringt es, Dinge komplizierter zu schreiben, wenn es eine einfachere Lösung gibt, wenn Sie eine Funktion verwenden dürfen, die nur in Bash verfügbar ist?

Es gibt eine Folgefrage: Gibt es konkrete Zahlen zur Geschwindigkeit von Bash vs. Dash?

Ich habe meine Schlussfolgerung hier veröffentlicht: https://github.com/guettli/programming-guidelines/blob/master/README.rst#portable-Shell-scripts

4
guettli

Erstens Portabilität. Nichts ist falsch, wenn Sie sicher sind, dass die Bash-Version (und vorzugsweise die gleiche oder eine neuere Version) überall dort verfügbar ist, wo Sie das Skript verwenden. Wenn Sie ein Entwickler oder Systemadministrator sind, der neben Ubuntu die Verwendung von Software unter einem Unix-ähnlichen Betriebssystem erwartet und bash hat oder nicht, werden Bashismen unter /bin/sh nicht verstanden.

Zweitens POSIX-Konformität. Wenn Sie Skripte schreiben und senden, um sie als Teil des Betriebssystems oder eines Projekts einzubeziehen, müssen diese häufig in der /bin/sh -Syntax vorliegen, was im Grunde der POSIX-Standard ist. /bin/sh wird häufig aus Leistungsgründen bevorzugt. Wenn Sie also Geschwindigkeit in Shell-Skripten, Bashismen und damit Bash benötigen, sollten Sie möglicherweise etwas vermeiden.

Kurz gesagt, Bashismen sind nicht schlecht. Es kommt wirklich auf den Kontext an, für den Sie ein Skript schreiben. Wenn es eine Gewissheit ist, dass bash verfügbar und nicht sehr veraltet sein wird, dann nutzen alle diese Funktionen - sie sind aus einem bestimmten Grund da.

11

Nichts als solches, wenn Sie wissen, dass Sie eine Bash-spezifische Funktion verwenden, und denken Sie daran, den Hashbang #!/bin/bash zu verwenden, anstatt anzunehmen, dass /bin/sh Bash ist.

In Ubuntu (und Debian) sind/waren "Bashismen" in #!/bin/sh Skripten meistens ein Problem, wenn die Standardeinstellung /bin/sh auf Dash anstatt auf Bash wie früher geändert wurde (siehe DashAsBinSh in Ubuntu) wiki ). Alle Skripte, die mit /bin/sh ausgeführt wurden, mussten auf Bashismen überprüft und korrigiert werden, um die von Dash unterstützten Standardfunktionen zu verwenden. Bei der Änderung ging es nicht um die Verfügbarkeit von Bash (es ist immer noch ein Essential -Paket, also immer installiert), sondern um die Geschwindigkeit: Bevor systemd gestartet wurde, wurden zahlreiche Shell-Skripte erstellt und die Standard-Shell wurde tatsächlich in eine schnellere geändert hatte einen Einfluss.

Auf anderen Systemen ist /bin/sh möglicherweise immer noch Bash, wodurch es möglich ist, in Skripten, die mit #!/bin/sh gekennzeichnet sind, versehentlich Bash-spezifische Funktionen zu verwenden. Sie würden nicht direkt in einem System funktionieren, in dem sh nicht Bash ist. Dann gibt es Systeme, die überhaupt keinen Bash haben. Eingebettete Systeme haben oft nur die Busybox Shell. Nicht-Linux-Unixen verfügen möglicherweise nicht über Bash, obwohl sie häufig eine Version von ksh haben, von der viele der Funktionen von Bash stammen. Sie sind jedoch nicht 1: 1 kompatibel.

Einige der nicht standardmäßigen Funktionen in Bash sind sehr nützlich (z. B. Arrays , Teilstring-Slices (${var:n:m}) , text replace (${var/foo/bar})). Wenn Sie das Schreiben Ihres Skripts erleichtern, verwenden Sie auf jeden Fall Bash.

Das heißt, es gibt einige Bashismen mit direkten Standardäquivalenten, was bedeutet, dass es keinen oder nur einen geringen Grund gibt, die nicht standardmäßige Variante zu verwenden. Einige, die mir einfallen:

  • der Operator == in [ .. ] ist nicht standardgemäß, entspricht jedoch dem Standardoperator =
  • function f { ... } und f() { ... } sind in Bash äquivalent, aber ersteres ist nicht Standard. (Es ist von ksh, wo es einen Unterschied gibt.)
  • $((--n)) ist kein Standard, kann aber durch $((n=n-1)) ersetzt werden
  • In einfachen Fällen kann [[ ... ]] durch den Standard [ .. ] ersetzt werden
6
ilkkachu