Script-Programmierung

Quoting und Sonderzeichen


In der bash sind eine Reihe von Sonderzeichen definiert, die besondere Aktionen der Shell auslösen.
Diese Sonderzeichen sind
ZeichenNameDezimalcodeOktalcodeHexadezimalcode
blank-Zeichen
<space>Leerzeichen320400x20
<tab>Tabulatorzeichen90110x09
meta-Zeichen
¦durchbrochener senkrechter Strich1241740x3C
&Ampersand-Zeichen, kaufmännisches Und380460x26
;Semikolon590730x3B
( )öffnende und schliessende runde Klammer40 41050 0510x28 0x29
< >öffnende und schliessende spitze Klammer60 62074 0760x3C 0x3E
<space>Leerzeichen320400x20
<tab>Tabulatorzeichen90110x09
Quotungszeichen
"doppeltes Anführungszeichen340420x22
'einfaches Anführungszeichen390470x27
\backslash-Zeichen921340x5C
Expansionszeichen
$Dollarzeichen360440x24
`Back-qoute-Zeichen961400x60
˜Tilde1261760x7E
{ }öffnende und schliessende geschweifte Klammer123 125173 1750x7B 0x7D
Kontrolloperatoren
¦durchbrochener senkrechter Strich1241740x3C
¦¦doppelter durchbrochener senkrechter Strich1241740x3C
&Ampersand-Zeichen, kaufmännisches Und380460x26
&&doppeltes Ampersand-Zeichen, kaufmännisches Und380460x26
;Semikolon590730x3B
;;doppeltes Semikolon590730x3B
( )öffnende und schliessende runde Klammer40 41050 0510x28 0x29
<newline>Zeilenumbruch100120x0A
Kommentarzeichen
#Doppelkreuz, Hash350430x23
Diese Zeichen werden nicht als normale ASCII-Zeichen interpretiert, sondern lösen spezielle Funktionen der bash aus die in anderen Abschnitten noch erklärt werden. Will man diese Sonderfunktion bestimmter Zeichen aufheben, da sie zB. in Parametern enthalten sind, so müssen diese Zeichen gequotet werden. Damit wird diese Sonderbedeutung aufgehoben und die Zeichen werden als ganz normale ASCII-Zeichen behandelt.

  1. meta-Zeichen
    Diese Zeichen spielen eine besondere Bedeutung beim Separieren des Datenstroms am Anfang der Interpretation durch die bash. Alle meta-Zeichen dienen dabei als Trennzeichen, um den Eingabedatenstrom in einzelne Worte aufzuspalten. Deshalb dürfen diese Zeichen auch nicht ungeschützt in Kommandonamen, Optionen oder Parametern verwendet werden, da sie zur Splittung führen und Sonderfunktionen der bash aktivieren.. Worte, Optionen und Parameter, die solche meta-Zeichen enthalten, sind auf jeden Fall durch Quotungszeichen zu schützen. Dadurch bleiben die meta-Zeichen vor der bash verborgen und werden nicht als Trennzeichen erkannt.
  2. Quotungszeichen
    Die Quotungszeichen dienen dazu, die Sonderzeichen vor der Interpretation durch die bash zu schützen. Die Wirkungsweise und der Wirkungsradius der Quotungszeichen ist unterschiedlich. Der backslach hat die stärkste Wirkung, da er sogar sich selbst quoten kann, aber den kleinsten Wirkungsradius, da er nur das folgende Zeichen quotet.
  3. Expansionszeichen
    Die Expansionszeichen leiten verschiedene Substitutions und Expansionsfunktionen der bash ein.
  4. Kontrolloperatoren
    Kontrolloperatoren dienen dazu, mehrere Kommandos zu gruppieren und dadurch mehrere Kommandos in einer Kommandozeile ausführen zu lassen. Die bash erkennt durch diese Operatoren, dass es sich um eine folge mehrerer Kommandos handelt und wird diese von links nach rechts abarbeiten.
  5. Kommentarzeichen
    Das Doppelkreuz leitet in Shellscripten einen Kommentar ein. Kommentare können an beliebiger Stelle eingefügt werden. Der gesamte Zeilenrest wird bei der Interpretation von der Shell ignoriert. Ein Spezialfall tritt auf, wenn auf ein Kommentarzeichen in der ersten Zeile des Scripts ein Ausrufezeichen folgt und auf dem Rest der ersten Zeile ein Interpreterprogramm benannt ist (z.B. #!/bin/bash). Wenn so eine Textdatei ausführbar ist und als Kommando aufgerufen wird, so wird diese Textdatei sofort an den entsprechenden Interpreter übergeben und durch diesen ausgeführt.

Dazu ein einfaches Beispiel:
Sie möchten die Datei mit dem Namen Mein Lebenslauf aus dem aktuellen Verzeichnis löschen und geben dazu den Befehl
rm Mein Lebenslauf
ein. Das Ergebnis wird in den meisten Fällen eine Fehlermeldung sein, die besagt, dass die Dateien Mein und Lebenslauf nicht existieren. Noch schlimmer ist es, wenn zB. die Datei Lebenslauf wirklich existiert hat und nun gelöscht wurde. Der Grund für diese Fehlermeldung ist recht einfach. Der Dateiname enthält ein Leerzeichen und dieses ist ein Sonderzeichen der bash. Es dient dazu, die einzelnen Worte in der Kommandozeile voneinander zu trennen (word-splitting). Die bash erkennt also nicht, dass das Leerzeichen ein Bestandteil des Dateinamens ist und geht davon aus, dass Sie zwei Dateien löschen möchten. Es werden die beiden Parameter Mein und Lebenslauf an das Kommando rm übergeben und dieses reagiert im günstigsten Fall mit der oben genannten Fehlermeldung.
Das Leerzeichen muss also seiner Sonderbedeutung enthoben werden und das geschieht durch Quotungszeichen. Diese Zeichen sind in der Lage, die Sonderbedeutung bestimmter Zeichen aufzuheben und damit die Sonderbehandlung dieser Zeichen durch die Shell zu verhindern. Wird ein Zeichen gequotet, so wird es wie jedes andere ASCII-Zeichen behandelt. Es dürfen auch Zeichen ohne Sonderbedeutung gequotet werden, dass hat dann keine weiteren Auswirkungen.
Wirkung der Quotungszeichen
Die Quotungszeichen wirken unterschiedlich stark.
\backslash

Ein nicht gequoteter backslash (\) ist der escape character. Der backslash hebt die Sonderbedeutung nur des folgenden Zeichens auf. Sollen mehrere Zeichen gequotet werden, so ist jedem dieser Zeichen ein backslash voranzustellen. Weiterhin können mit dem backslash auch nicht druckbare Zeichen erzeugt werden.
Weitere backslash escape-sequenzen sind:

\aalert (bell)
\bbackspace
\eescape character ESC 27
\fform feed
\nnew line
\rcarriage return
\thorizontal tab
\vvertical tab
\\backslash
\'single quote
\nnnZeichencode in oktaler Kodierung
\xHHZeichencode in hexadezimaler Kodierung
\cxcontrol-x character

Eine besondere Bedeutung hat ein gequotetes <newline>, also die Zeichenkombination \<newline>, wobei der backslash nicht selbst gequotet sein darf. Diese escape-Sequenz bewirkt eine Fortsetzung der Eingabezeile auf der nächsten Terminalzeile. Der gequotete backslash wird dabei aus dem Datenstrom entfernt und ist effektiv nicht vorhanden. Damit kann die Eingabezeile auf mehrere Terminalzeilen ausgedehnt werden.

'single quote, einfaches Anführungszeichen
Alle Zeichen und Worte, die zwischen den single quotes ' eingeschlossen sind, verlieren ihre Sonderbedeutung, ausgenommen der single-quote selbst. In einem mit single-quotes gequoteten String darf selbst kein ungequotetes single-quote enthalten sein.
"double quote, doppeltes Anführungszeichen
Alle Zeichen und Worte, die zwischen den double quotes " eingeschlossen sind, verlieren ihre Sonderbedeutung, ausgenommen $,`, " und \. Die Zeichen $ und ` behalten ihre Bedeutung innerhalb der double quotes " bei. Der backslash wirkt mit seiner Sonderbedeutung nur noch, wenn er von einem der Zeichen $, `, ", \, oder gefolgt wird. Innerhalb von double quotes müssen double quotes mit dem backslach gequotet werden. Die Parameter * und @ haben innerhalb der double quotes eine besondere Bedeutung. Die Ausdrücke der Form $'string' haben eine besondere Bedeutung.
Nachdem die bash die Kommandozeile bearbeitet hat, entfernt es die Quotingzeichen und führt dann das Kommando aus. Wenn also zb eine Variablenzuweisung mit
TEST="der Test"
vorgenommen wird, dann weist die bash der Variable TEST den Wert der Test zu. Sie hat also den Text mit Leerzeichen als einen Parameter erkannt, da mit double quotes " gequotet wurde. Die Quotungszeichen selbst werden aber entfernt und werden nicht mit in der Variable gespeichert.
Für das oben angeführte Beispiel würde das also bedeuten, dass der korrekte Kommandoaufruf so aussehen könnte:
rm "Mein Lebenslauf"
oder
rm 'Mein Lebenslauf'
oder
rm Mein\ Lebenslauf
Besonders wichtig und beachtenswert ist das Quoting, wenn der Parameter durch Substitution oder Expansionen erzeugt wird. In unserem Fall würde das bedeuten, wenn der Dateiname für das rm-Kommando in einer Variable enthalten ist und durch Parametersubstitution eingefügt wird. Das Script
#!/bin/bash
..........
rm ${DATEINAME}
..........
würde nur korrekt funktionieren, wenn der Dateiname in der Variablen DATEINAME nicht selbst ein Leerzeichen enthält. Wenn doch, dann kommt es zu dem oben genannten Problemen. Besser ist also
#!/bin/bash
..........
rm "${DATEINAME}"
..........
, weil damit sichergestellt wird, dass die bash angewiesen wird, den der Inhalt der Variablen DATEINAME als einen Parameter zu interpretieren, auch wenn Leerzeichen darin vorkommen.