Script-Programmierung
Quoting und Sonderzeichen
In der bash sind eine Reihe von Sonderzeichen definiert, die besondere Aktionen der Shell auslösen.
Diese Sonderzeichen sind
| Zeichen | Name | Dezimalcode | Oktalcode | Hexadezimalcode |
| blank-Zeichen |
| <space> | Leerzeichen | 32 | 040 | 0x20 |
| <tab> | Tabulatorzeichen | 9 | 011 | 0x09 |
| meta-Zeichen |
| ¦ | durchbrochener senkrechter Strich | 124 | 174 | 0x3C |
| & | Ampersand-Zeichen, kaufmännisches Und | 38 | 046 | 0x26 |
| ; | Semikolon | 59 | 073 | 0x3B |
| ( ) | öffnende und schliessende runde Klammer | 40 41 | 050 051 | 0x28 0x29 |
| < > | öffnende und schliessende spitze Klammer | 60 62 | 074 076 | 0x3C 0x3E |
| <space> | Leerzeichen | 32 | 040 | 0x20 |
| <tab> | Tabulatorzeichen | 9 | 011 | 0x09 |
| Quotungszeichen |
| " | doppeltes Anführungszeichen | 34 | 042 | 0x22 |
| ' | einfaches Anführungszeichen | 39 | 047 | 0x27 |
| \ | backslash-Zeichen | 92 | 134 | 0x5C |
| Expansionszeichen |
| $ | Dollarzeichen | 36 | 044 | 0x24 |
| ` | Back-qoute-Zeichen | 96 | 140 | 0x60 |
| ˜ | Tilde | 126 | 176 | 0x7E |
| { } | öffnende und schliessende geschweifte Klammer | 123 125 | 173 175 | 0x7B 0x7D |
| Kontrolloperatoren |
| ¦ | durchbrochener senkrechter Strich | 124 | 174 | 0x3C |
| ¦¦ | doppelter durchbrochener senkrechter Strich | 124 | 174 | 0x3C |
| & | Ampersand-Zeichen, kaufmännisches Und | 38 | 046 | 0x26 |
| && | doppeltes Ampersand-Zeichen, kaufmännisches Und | 38 | 046 | 0x26 |
| ; | Semikolon | 59 | 073 | 0x3B |
| ;; | doppeltes Semikolon | 59 | 073 | 0x3B |
| ( ) | öffnende und schliessende runde Klammer | 40 41 | 050 051 | 0x28 0x29 |
| <newline> | Zeilenumbruch | 10 | 012 | 0x0A |
| Kommentarzeichen |
| # | Doppelkreuz, Hash | 35 | 043 | 0x23 |
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.
- 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.
- 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.
- Expansionszeichen
Die Expansionszeichen leiten verschiedene Substitutions und Expansionsfunktionen der bash ein.
- 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.
- 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:
| \a | alert (bell) |
| \b | backspace |
| \e | escape character ESC 27 |
| \f | form feed |
| \n | new line |
| \r | carriage return |
| \t | horizontal tab |
| \v | vertical tab |
| \\ | backslash |
| \' | single quote |
| \nnn | Zeichencode in oktaler Kodierung |
| \xHH | Zeichencode in hexadezimaler Kodierung |
| \cx | control-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.