Bessere Shell-Skripte
Shell-Skripte sind gegenüber anderen Programmiersprachen natürlich nicht das "Non-plus-ultra", aber sie sind für Ablaufsteuerungen - dafür sind sie gemacht - eine gute Wahl. Für alles, was grösser ist, empfehle ich eine "richtige Programmiersprache". Ich bin als Systemadministrator ein grosser Fan von Python und - schon länger nicht mehr genutzt - Perl, aber auch Sprachen wie Raku, Ruby oder irgendetwas mit Compiler sind natürlich gute Alternativen.
Ich beziehe mich im Folgenden auf die Bash, weil das die Shell ist, die ich täglich auf verschiedenen Systemen und Architekturen benutze.
Tipp 1:
Schreibt in den Shebang #!
zu Beginn des Skriptes genau die Skriptsprache mit der Ihr auch getestet habt und nicht - weil alle das machen - /bin/sh
. Auf Debian basierten Systemen ist /bin/sh
ein Link auf dash
, bei Alpine ist es ein Link auf Busybox, auf Red Hat basierten Systemen ein Link auf bash
.
An dieser Stelle möchte ich gerne noch auf diesen alten Artikel hinweisen.
Tipp 2:
Skripte laufen auch im Falle eines Fehlers weiter. Ich halte das für ein blödes Verhalten, was sehr häufig zu Fehlern führt. Glücklicherweise kann man das Verhalten abstellen.
Entweder man ruft die Shell mit -e
auf, setzt den Shebang entsprechend oder schreibt set -e
an den Anfang des Skriptes oder vor die Zeilen für die das Setting gelten soll. Mit set +e
kann man wieder das alte Verhalten herstellen.
Meine Empfehlung ist, die Langform set -o errexit
zu verwenden, das ist deutlich lesbarer. (Altes Verhalten kann man mit set +o errexit
wieder herstellen).
Shellzeilen gelten als fehlerhaft, wenn der exit-Code des letzten Kommandos der Zeile ungleich 0 (null) ist. Das bedeutet unter anderem, dass man den Exitcode einer einzelnen Zeile durch Hinzufügen von || true
auf "nicht fehlerhaft" ändern kann.
Tipp 3:
Wie im letzten Tipp beschrieben, ist das letzte ausgeführte Kommando einer Zeile ausschlaggebend dafür, ob eine Zeile mit oder ohne Fehlercode beendet wird.
Der Eintrag set -o pipefail
sorgt dafür, dass eine Zeile als fehlerhaft "gesehen" wird, wenn auch nur ein Kommando der über Pipes vernetzten Kommandos einer Zeile fehlschlägt.
Tipp 4:
Nicht gesetzte oder "leere" Variablen sind häufig ein Problem.
Um eine nicht gesetzte Variable mit einem Fehler zu quittieren, kann man das Kommando set -o nounset
oder set -u
verwenden.
Tipp 5:
Es ist generell eine gute Idee, alle Variablen mit doppelten Anführungszeichen zu umgeben, ganz besonders dann, wenn es um Dateien geht. Auch, wenn man selber keine Dateien mit Leerzeichen (oder anderen "Internal Field Separators" (IFS)) erstellt, heisst es nicht, dass man nicht auf solche treffen kann.
Nachtrag:
Christoph hat in diesem Kommentar zur recht darauf hingewiesen, dass es besser ist /usr/bin/env bash
zu verwenden, das benutzt die erste Bash, die der Benutzer im Pfad hat und funktioniert auch auf Systemen, auf denen die Bash in einem anderem Pfad liegt als /bin/bash
.
Zusammenfassung:
Meine Erfahrung ist, dass man mit den fünf Tipps rund 80% aller Probleme mit Shellskripten umschifft bzw. Skripte mit Fehlern rechtzeitig abbricht.
set -o errexit
set -o nounset
set -o pipefail
# Und Variablen immer mit doppelten Anführungszeichen verwenden.
echo "${Variable}"
Es gibt noch viele weitere Tipps, aber das sind meiner Ansicht nach die wichtigsten.
Kommentare
Ansicht der Kommentare: Linear | Verschachtelt
Christoph Stoettner am :
zu benutzen, das hat mir in Zusammenhang mit Dash/Bash etc weit weniger Probleme bereitet. S.a. https://www.cyberciti.biz/tips/finding-bash-perl-python-portably-using-env.html
Dirk Deimeke am :
Ich ergänze das mal im Artikel.
Christoph Stoettner am :
heissen.
Dirk Deimeke am :
tux. am :
Dirk Deimeke am :
Das hast Du aber auch mit Shellskripten.
tux. am :
Dirk Deimeke am :
Das Problem habe ich nicht auf Enterprise-Linux-Distributionen. Gut, da habe ich das auch nicht mit Python.
Christoph Petrausch am :
Dirk Deimeke am :
Fryboyter am :
tux. am :
Dirk Deimeke am :
Den Leuten bei ShellCheck sollte man mal sagen, dass sie sh explizit ausklammern müssen.
Dirk Deimeke am :
Christoph Petrausch am :
Dirk Deimeke am :
Ich kenne einige Unternehmen, die einen verbindlichen Styleguide für jede Programmiersprache einsetzen und wenn ich mich richtig erinnere, sind die von Google sogar öffentlich.
Gefunden: Shell Style Guide
Bruno am :
https://octodon.social/@eptf/105080666953522366
Dirk Deimeke am :