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.