Unix Shell Programmierung mit sh kompatiblen Shells |
In vielen Fällen lässt es sich unter Unix vermeiden ein spezielles compiliertes Program zu schreiben, weil durch Aufrufen einzelner anderer Programme und die Bearbeitung der Ausgaben und Eingaben dieser einfacher die Funktionalität dargestellt werden kann. Die Programme die Eingaben an der Tastatur entgegen nehmen, diese entsprechend interpretieren und ein anderes Program ausführen sind weithin als Shells bekannt. Moderne Shells bieten viele Möglichkeiten mit ihnen auch richtige Programme zu erstellen.
Hier werden einige grundlegende Konzepte der Programmierung in der POSIX normierten sh vorgestellt.
Allgemeines |
Im allgemeinen ist es egal, ob man Kommandos einzeln auf der Kommandozeile eingibt oder in einer Datei zur wiederholten Abarbeitung ablegt.
Das aktuelle Verzeichnis (working directory) ist immer jenes, in dem das Skript aufgerufen wird. Natürlich ist es auch möglich das nachträglich mit 'cd' zu wechseln.
Variablen |
"Normale" Variablen |
Durch ein einfaches
|
Environment Variablen |
Das Environment eines Prozesses sind externe Variablenbelegungen, die einem Programm beim Start mitgegeben werden, von diesem modifiziert werden und an seine Kindprozesse weitergegeben wird.
In der sh kann eine Variable durch
|
Expandieren von Variablen |
Variablen werden mit
|
Wildcards |
Die einfachen "Glob" Wildcards in POSIX kennen folgende Elemente:
Interpretation einfacher Kommandos |
Nach der Bestätigung des Befehls auf der Kommandozeile wird dieser einmal an Spaces und TABs zerlegt. Variablen und andere Spezialitäten werden expandiert. Dann wird das Kommando exekutiert.
Will man spezielle Zeichen der sh (Globs, Leerzeichen oder ähnliches) "escapen" (also unschädlich machen) kann man für einzelne Vorkommen den "\" benutzen. Für längere Abschnitte kann man einfache oder doppelte Anführungszeichen benutzen. Dabei unterdrücken einfache Anführungszeichen die Variablenerweiterung, doppelte nicht.
Ein-/ Ausgabe |
Ein Prozess hat drei Standard Filedeskriptoren:
|
Durch Anhängen spezieller Konstrukte können diese Deskriptoren in verschieden Arten verdreht werden:
|
Dabei werden i.A. tatsächlich auf OS-Ebene die Filedeskriptoren (SprachPolizei?) verknüpft, sodaß direkte Kommunikation stattfindet.
Kommandos verknüpfen |
Kommandos können zu sogenannten Listen verknüpft werden. Dabei wird der Exit-Status der Programme als boolsche Werte interpretiert: 0 ist TRUE und ungleich 0 ist FALSE. Wie aus anderen Sprachen gewohnt werden "&&" und "||" mit Shortcutting (SprachPolizei) evaluiert.
Der Strichpunkt (";") ist ein einfacher Statement Seperator mit niedrigerem Vorrang ("precedence") als "&&" und "||".
Einfache runde Klammern starten die geklammerte Liste in einem eigenen Prozess (sog. Subshell) und können daher zur Vorrangbestimmung eingesetzt werden.
Beispiel |
Das Programm prog ausführen und bei erfolgreicher Beendigung "OK" sonst "FAIL" ausgeben.
|
Jene die einen Tip brauchen, dürfen in den /Lösungen nachschauen.
Kommando Ersetzung (Command Substitution) |
Um den Output einer Liste weiterzuverwenden kann man diesen mit [Code]`liste`] in die Kommandozeile einbauen.
|
Konditionale |
|
Schleifen |
|
Die list wird für jedes wort aus der wortliste mit variablenname=wort ausgeführt.
|
Solange der Exit-Status von bedingungs_list null ist, wird body_list wiederholt.
Kommandozeilenparameter |
Werden der sh Argumente auf der Kommandozeile übergeben, so kann man diese in verschiedener Art verwenden.
Beispiel:
|
Direkte Adressierung:
|
liefert
|
Indirekte Addressierung:
|
liefert
|
Mit einer Schleife kann dabei die gesamte Kommandozeile abgearbeitet werden.
Spezialitäten |
Will man die gesamte (verbleibende) Kommandozeile unverändert weiterreichen so benutzt man am besten
|
|
Zur Demonstration des Unterschiedes nehmen wir ein File mit dem Namen "space space" und eines mit dem Namen "space" im aktuellen Verzeichnis an und schreiben dieses Skript:
|
Probieren wir das einmal aus:
|
Wie man sieht konnte beim ersten Mal das Leerzeichen gerettet werden. Beim zweiten Mal hat die sh zugeschlagen und die Kommandozeile erneut geparst, weshalb nicht ls -l 'space space' space sondern ls -l space space space ausgeführt wurde.
PitFalls? |
Da sh-kompatible Shells WhiteSpace zum tokenizen benutzen, sind folgende Befehle nicht gleichwertig
|
und werden so interpretiert:
|
FeedBack |
Wollt ihr mehr oder lest ihr Euch eh brav die man-page durch? ;-))