Warum iteriert die Bourne-Shell printf
über ein %s
Argument?
Bei der Arbeit mit Shell-Skripten sind viele Programmierer über bestimmte Verhaltensweisen von Befehlen verwirrt. Ein solches Beispiel tritt auf, wenn die printf
-Funktion der Bourne-Shell verwendet wird, insbesondere mit Strings als Argumenten. Wenn Sie jemals unerwartete Ausgaben beim Versuch, eine Variable mit printf
anzuzeigen, erlebt haben, sind Sie nicht allein! Lassen Sie uns ergründen, warum dies passiert und wie man das Problem lösen kann.
Problemanalyse
Betrachten Sie das folgende einfache Shell-Skript:
#! /bin/sh
NAME="George W. Bush"
printf "Hello, %s\n" $NAME
Wenn Sie dieses Skript ausführen, könnten Sie annehmen, dass die Ausgabe einfach wäre: Hello, George W. Bush
. Zu Ihrer Überraschung gibt die Befehlszeile jedoch zurück:
Hello, George
Hello, W.
Hello, Bush
Was passiert hier?
Das Problem liegt in der Art und Weise, wie die Shell die Variable erweitert. Wenn Sie $NAME
ohne Anführungszeichen verwenden, trennt die Shell den Inhalt der Variable NAME
nach Leerzeichen und behandelt jeden Teil als separates Argument. Daher wird printf
mit drei Argumenten aufgerufen: George
, W.
und Bush
. Jedes dieser Argumente wird einzeln verarbeitet, was zu dem unerwarteten Verhalten führt, das Sie sehen.
Der richtige Ansatz
Um dieses Problem ganz zu vermeiden, müssen Sie die Variable in Anführungszeichen setzen. Hier ist die korrigierte Version Ihres Skripts:
#! /bin/sh
NAME="George W. Bush"
printf "Hello, %s\n" "$NAME"
Warum Anführungszeichen wichtig sind
Wenn Sie $NAME
in Anführungszeichen setzen, teilen Sie der Shell mit, dass der gesamte Inhalt – einschließlich der Leerzeichen – ein einzelnes Argument ist. Dies ist entscheidend für Strings, die Leerzeichen enthalten, da es sie während der Variablenexpansion intakt hält.
Alternativen: Warum nicht echo
verwenden?
Sie fragen sich vielleicht, warum man nicht einfach echo
anstelle von printf
verwenden sollte. Hier ist ein Vergleich zwischen den beiden im Kontext eines anderen Beispiels:
#! /bin/sh
FILE="C:\tmp"
echo "Filename: $FILE"
Wenn Sie dieses Skript ausführen, ergibt sich:
Filename: C: mp
Dieses Verhalten zeigt die Probleme, die auftreten können, wenn man echo
verwendet, insbesondere mit Rückwärtsschrägstrichen und Escape-Sequenzen. Laut der POSIX-Spezifikation für echo
: “Neue Anwendungen werden ermutigt, printf
anstelle von echo
zu verwenden.” Diese Empfehlung spricht für das vorhersehbarere Verhalten und die Vielseitigkeit von printf
bei der Formatierung von Ausgaben.
Fazit
Zusammenfassend ist es wichtig zu beachten, dass Sie beim Gebrauch von printf
in Shell-Skripten immer doppelte Anführungszeichen um Variablen verwenden sollten, die Leerzeichen oder Sonderzeichen enthalten können. Dies stellt sicher, dass Ihre Ausgabe wie erwartet funktioniert und unerwartete Überraschungen verhindert. Mit dieser kleinen Anpassung können Sie printf
in Ihren Skripten sicher für saubere und kontrollierte Ausgaben verwenden!
Durch die Anwendung solcher Best Practices werden Sie in der Lage sein, robustere und zuverlässigere Shell-Skripte zu erstellen.