Aus Linux-Magazin 10/2009

Shellskripte aus der Stümper-Liga - Folge 1 (Seite 2)

Das Ergebnis stellt dennoch nicht zufrieden, da die For-Schleife die Leerzeichen in den Dateinamen als Trenner auffasst. Abbildung 2 verdeutlich das Desaster. Das liegt daran, dass der Unterprozess »ls« seine Daten über die Standardausgabe zum aufrufenden Shellskript überträgt. Dort ist nicht mehr vermerkt, wo ein einzelnes Listenelement endet.

Listing 3: Substituionen
iterieren

01 #!/bin/bash
02 for i in $(ls -- *.txt); do
03     echo "$i ..."
04 done
Abbildung 2: Leerzeichen in Kommandosubstitionen führen ohne Vorsichtsmaßnahmen leicht zu Datenmüll. Ohne richtiges Quoting wirken sie als Trenner.

Abbildung 2: Leerzeichen in Kommandosubstitionen führen ohne Vorsichtsmaßnahmen leicht zu Datenmüll. Ohne richtiges Quoting wirken sie als Trenner.

Daher ist es in diesem Fall besser, das Ergebnis des letzten Befehls zeilenweise zu verarbeiten. Die While-Schliefe aus Listing 4 setzt dieses Prinzip um. Hier steht das Kommando einzeln, über Pipes ließen sich auch einfach weitere Bearbeitungsstufen einfügen, etwa durch »grep« oder »sed«. Anschließend leitet das Programm seine Ausgabe in die While-Schleife von Zeile 3 um. Sie läuft solange wie die Bash noch eine Input vorfindet und zeilenweise in der Variable »i« speichert, die sich später mit »$i« auslesen lässt.

Listing 4: Zeilenweise
arbeiten

01 #!/bin/sh
02 ls -- *.txt |
03 while read i; do
04     echo "$i ..."
05 done

Arglistige Argumentlisten

Eine ähnliche Problematik tritt auf, wenn ein Shellskript vom Aufrufer eine a priori unbekannte Anzahl von Parametern erhält. Die ersten neun Argumente ruft ein Programmierer durch »$1« bis »$9« ab, mit dem Shell-Befehl »shift« lässt sich das erste Argument entfernen, alle anderen rutschen dann nach. Alle Argumente auf einmal legt die Bash in der Variable »$*« ab, allerdings erneut ohne nach Argumentgrenzen zu trennen. Wer Listing 5 mit dem Aufruf »demo.sh apfel “bittere birne” coole kiwi« startet, erhält

...apfel...
...bittere...
...birne...
...coole...
...kiwi...

als Ausgabe. Um dieses Problem zu lösen, gibt es die ähnlich arbeitende Variable »$@«. Im normalen Kontext arbeitet sie genau wie »$*«. Schließt sie der Bash-Hacker jedoch in doppelte Anführungszeichen ein und verwendet sie in einem Listenumfeld wie der For-Schleife, so überträgt die Shell die Elemente einzeln. Listing 6 zeigt das korrekte Skript.

Listing 5: Parameter
auflisten

01 #!/bin/sh
02 for i in $*; do
03     echo "...$i..."
04 done

Listing 6: Variante versteht
Blanks

01 #!/bin/sh
02 for i in "$@"; do
03     echo "...$i..."
04 done

Leer, kein und nichts

Die Variable »$@« eignet sich auch dazu, ganze Kommandozeilen an weitere Befehle zu übergeben, etwa durch »cat “$@”«, das auf diese Weise auch die Dateien mit Leerzeichen im Namen ausgibt. Sollte das Programm aber gar keine Parameter erhalten, entsteht gleich das nächste Problem: Die Variable expandiert dann zum leeren String »””«. Einem Kommando wie »cat« übergeben, versucht dieses erfolglos eine Datei mit leerem Namen zu öffnen [1].

Aus diesem Grund verwenden Bash-Profis bei solchen Gelegenheiten das Konstrukt »${1+”$@”}«. Es bedeutet, dass die Shell zunächst »$1« überprüft (die geschweiften Klammern dienen zur Klarheit und dürfen immer um die Ausdrücke nach dem Dollarzeichen stehen). Der Plus-Modifier findet so heraus, ob diese Variable überhaupt definiert ist und einen Wert besitzt. Gibt es also mindestens ein Argument, so verwendet die Shell den Ausdruck »$@«. Andernfalls expandiert sie zu gar nichts, nicht einmal einem leeren Dateinamen [2].

Leerschritte und Sonderzeichen sind also kein Teufelswerk, robuste Skripte kommen damit klar. In Schleifenkontexten zwingt gerade das Space Entwickler dazu, genau nachzudenken, ob die Liste das Zeichen als Trenner verwendet. Wer zeilenweise vorgeht, agiert auf der sicheren Seite. Argumente übergeben Entwickler am besten mit »$@« und dem richtigen Quoting.

Infos

[1] Tutorium für die Bourne Shell:[http://www.grymoire.com/Unix/Sh.html]

[2] Bourne Again Shell:[http://gnu.org/software/bash/]

DIESEN ARTIKEL ALS PDF KAUFEN
EXPRESS-KAUF ALS PDFUmfang: 2 HeftseitenPreis €0,99
(inkl. 19% MwSt.)
LINUX-MAGAZIN KAUFEN
EINZELNE AUSGABE Print-Ausgaben Digitale Ausgaben
ABONNEMENTS Print-Abos Digitales Abo
TABLET & SMARTPHONE APPS Readly Logo
E-Mail Benachrichtigung
Benachrichtige mich zu:
0 Kommentare
Älteste
Neuste Beste Bewertung
Inline Feedbacks
Alle Kommentare anzeigen
Nach oben