Next: cat
Up: Von GNU's, Muscheln und
Previous: basename
Die Frage, wie die Auswahl eines konkreten Programms stattfindet, ist
ebenso trivial wie bodenlos tiefgründig. Die Antwort ist ein
Metaprogramm, das automatisch geladen wird und dessen Hauptaufgabe es
ist, weitere Programme zu laden. Unter UNIX und seinen Verwandten
wird so ein Programm als Shell bezeichnet. Sie hat, im Gegensatz zu
vielen vergleichbaren Programmen anderer Betriebssysteme, den Status
eines Benutzerprogramms und kann deshalb nach Belieben ausgetauscht
werden.
An der Benutzeroberfläche entfesselt sich leicht eine Art Glaubenskrieg zwischen den Protagonisten unterschiedlicher Modelle. Zwischen den grafischen (mausgesteuerten, bildschirmorientierten) und den textuellen (tastaturgesteuerten, zeilenorientierten) Benutzeroberflächen scheinen sich die Geister zu scheiden. Die Vorteile der grafischen Benutzerführung liegt vor allem in ihrer leichten Erlernbarkeit. Durch die Präsentation der möglichen Aktionen in Menüs kann der ungeübte Benutzer intuitiv den Weg zu seiner Problemlösung finden. Zeilenorientierte Oberflächen, sogenannte Kommandozeileninterpreter, haben ihren Vorteil in der Vielseitigkeit. Während in einem Menüsystem zwangsläufig nur die Funktionen zu erreichen sind, für die es Menüeinträge gibt, können im Kommandozeileninterpreter alle Kommandos mit allen zulässigen Optionen aufgerufen werden. Genau diese Vielseitigkeit macht den Kommandozeileninterpreter - die Shell - zu einem unverzichtbaren Werkzeug der Systemverwalterin, das auch in kommerziellen Systemen mit menügesteuerter Administratorshell nicht ersetzt werden kann.
Die ,,Standardshell`` von AT&T Unix ist die nach ihrem Entwickler Steven R. Bourne benannte Shell (die unter der Kommandobezeichnung sh aufgerufen wird). Neben ihren Diensten als interaktiver Kommandozeileninterpreter bietet die Bourne-Shell noch eine mächtige Sprache zum Erstellen von Shellprogrammen. Solche Shellscripts erlauben schnell und unkompliziert die Zusammenfassung immer wiederkehrender Kommandofolgen als Batchdatei. Die Möglichkeiten der Shellprogrammierung gehen aber noch viel weiter, wie die weiter hinten folgende Beschreibung zeigen wird.
Neben der ,,alten`` Bourne-Shell gibt es noch eine ganze Reihe weiterer Shells. Andere bekannte Shells sind die an der Berkeley Universität entwickelte csh und die nach ihrem Entwickler David Korn benannte Shell ksh. Die Shells unterscheiden sich vor allem in den Shellsprachen, sie haben aber auch neue Eigenschaften zur Erleichterung der interaktiven Benutzung als Kommandozeileninterpreter. Die ,,Bourne Again Shell`` bash vereint die altbekannte und bewährte Shellsprache der Bourne Shell mit den fortschrittlichen und beliebten Interaktionsfunktionen der anderen Shells. Die bash ist als Standardshell in allen Linux-Distributionen enthalten.
Es ist erklärter Anspruch der bash, zur Standard-Bourne-Shell kompatibel zu sein, und Ziel ist die volle Übereinstimmung mit dem POSIX-1003.2-Standard. Die Kompatibilität zur Bourne-Shell ist besonders wichtig, um die vielen Shellscripts für diese Standardshell auch mit der bash benutzen zu können.
Die alltägliche Arbeit mit der Shell findet interaktiv statt. Das heißt, die Shell gibt eine Eingabeaufforderung (Prompt) aus, die vom Benutzer mit einer Folge von Tastatureingaben, der Kommandozeile, beantwortet wird. Eine Kommandozeile wird durch ein Zeilenendezeichen (RETURN) abgeschlossen. Die Shell interpretiert daraufhin die eingegebene Zeile und führt die gegebenenfalls darin formulierten Kommandos aus. Normalerweise gibt die Shell nach der vollständigen Bearbeitung der Kommandozeile wieder eine Eingabeaufforderung aus, um den gleichen Vorgang erneut einzuleiten.
Für die Shell macht es wenig Unterschied, ob sie eine Kommandozeile direkt von der Tastatur liest, oder ob sie die gleiche Zeile aus einem ,,eingefrorenen Datenstrom``, einer Datei, erhält. Für den Anwender ist es enorm praktisch, immer wiederkehrende Kommandofolgen in einer Textdatei zusammenzufassen und dann diese Datei anstelle der Tastatureingabe bearbeiten zu lassen. Genau das ist der Ursprung der Shellprogrammierung.
In der Realität bieten alle Unix-Shells Programmiersprachen, die weit über diese Stapelverarbeitung (sogenannte Batch-Jobs) hinausgehen. Es können Variable benutzt werden, Verzweigungen und Schleifen sind möglich, es können sogar Script-Funktionen definiert werden, die eine strukturierte Programmierung wie in den bekannten Hochsprachen erlauben.
Nun besteht umgekehrt kein vernünftiger Grund, weshalb die Elemente der Shellprogrammierung nicht auch auf der Kommandozeile verwendet werden sollten. Natürlich wird niemand ein zig-zeiliges Shellprogramm direkt auf der Kommandozeile eingeben. Andererseits macht es wenig Sinn, für jede vierzeilige for-Schleife ein Shellscript zu schreiben.
Damit wird klar, daß die Grenzen zwischen interaktiver Benutzung und Shellprogrammierung fließend sind. Je nach Blickwinkel werden aber die Schwerpunkte anders gesetzt. Diese Beschreibung richtet sich in erster Linie an interaktive Benutzer. Sie erhebt aber auch den Anspruch auf Vollständigkeit. Um den Text einigermaßen lesbar zu machen, sind die Abschnitte mit ausgesprochen shellscriptspezifischen Inhalten in einem kleineren Schriftgrad gedruckt. Solche Textteile können beim ersten Lesen übersprungen werden.
Diese primitiven Funktionen werden vom Terminaltreiber des Kernels im
,,cooked``-Modus direkt angeboten. Die bash
bietet darüber hinaus einen Kommandozeileneditor, der in Umfang und
Funktion den Standardeditoren vi und emacs
nachempfunden ist.
Sie können die Funktionen
des Kommandozeileneditors Ihren eigenen Bedürfnissen
anpassen.
Zwischen den Standardbelegungen kann mit dem
set-Shellkommando umgeschaltet werden. Normalerweise arbeitet
der Kommandozeileneditor im emacs-Modus.
Die Editorbefehle im emacs-Modus benutzen zwei
Sondertasten: die CONTROL- und die Metataste. Die CONTROL-Taste ist auf der PC-Tastatur in
der linken unteren Ecke (manchmal STRG). Eine Metataste ist
unter diesem Namen in der Regel nicht vorhanden. Meistens wird die
linke ALT-Taste mit dieser Funktion belegt. Wenn
das nicht der Fall ist, kann die ESCAPE-Taste (ESC) benutzt werden. Während CONTROL und ALT gemeinsam
mit dem Buchstaben gedrückt werden müssen, wird ESC vor dem
Buchstaben gedrückt (zwei Anschläge).
In den Erklärungen wird CONTROL mit `C-' und die Metataste mit `M-' gekennzeichnet. In manchen Fällen müssen CONTROL und ALT zusammen gedrückt werden, das wird dann durch M-C- symbolisiert.
Positionieren der Einfügemarke
Automatische Erweiterung von Kommando- und Dateinamen
Probieren Sie diese Funktion des Kommandozeileneditors einfach aus. Sie werden schnell merken, wie mächtig und vielseitig sie ist.
Wenn ein Wort mehreren bekannten Namen zugeordnet werden kann, wird
es nur so weit ergänzt, wie sich die Namen nicht unterscheiden. Wenn
dann ein zweites Mal TAB gedrückt wird, werden alle erkannten
Möglichkeiten angezeigt.
(complete)
Verschiedenes
Die Anzahl der gespeicherten Kommandozeilen kann mit der Shellvariablen HISTSIZE eingestellt werden. Weitere Einstellungen können mit den Variablen HISTFILE HISTFILESIZE und history_control vorgenommen werden. Die Benutzung dieser Variablen wird hier beschrieben.
Wie alle Funktionen des Editors kann diese Funktion auf beliebige Tasten gelegt werden, wenn auch in diesem Fall davon abzuraten ist. (accept-line)
In der C-Shell ist es möglich, einzelne Wörter aus bestimmten Kommandozeilen im Kommandozeilenspeicher in die aktuelle Kommandozeile zu integrieren. Dazu wird zuerst eine Kommandozeile referenziert und danach ein Wort in dieser Kommandozeile angesprochen.
Anstelle des Ausrufezeichens kann in der Shellvariablen histchars auch ein anderes Zeichen mit dieser Funktion belegt werden.
!!:s^Alt^Neu^ zur Ersetzung der Zeichenkette Alt
durch Neu in der letzten Kommandozeile. Diese
Konstruktion muß allein auf der Kommandozeile stehen.
^',
`$', `*' oder `%' beginnt, kann der
Doppelpunkt auch weggelassen werden. Die Wörter einer Kommandozeile
sind vom Zeilenanfang an mit Null beginnend numeriert.
Auf den ersten Blick ist die C-Shell History-Funktion wahrscheinlich etwas spröde. Die folgenden Beispiele zeigen einige Vorteile dieser Funktion bei der täglichen Arbeit mit der C-Shell.
Häufig wird eine Datei in ein Verzeichnis verschoben und unmittelbar anschließend das aktuelle Verzeichnis dorthin gewechselt.
$ mv broo.fazz.tar.gz /ftp/pub/comp/i386/Linux/utils/misc $ cd !$ $ _Mit `!$' wird das letzte Wort der vorhergehenden Kommandozeile eingefügt. Das gleiche Ergebnis wird auch durch die META-.- Funktion des Kommandozeileneditors ausgeführt.
Gelegentlich braucht man nicht das komplette Argument, sondern nur einen Teil davon:
$ less /usr/X386/include/X11/Xaw/SmeBSBP.h $ find /usr/src/X11 -name !:t find /usr/src/X11 -name SmeBSBP.h find: /usr/src/X11: No such file or directory $ _Der Operator !:t liefert SmeBSBP.h. Hier kann die Referenz auf das letzte Argument weggelassen werden, weil die :t-Operation nur die Zeichen nach dem letzten Slash liefert.
Sehr nützlich ist auch die schnelle Substitution einer Zeichenfolge:
$ tar -tvzf /ftp/pub/Incoming/das.ist.neu.tar.gz [Ausgabe von tar] $ ^tv^x tar -xzf /ftp/pub/Incoming/das.ist.neu.tar.gz $ _Hier werden die tar-Optionen -tv durch -x ausgetauscht. Zuerst wird also der Inhalt des Archivs angezeigt, dann wird es im nächsten Schritt ausgepackt. Mit dieser Methode lassen sich ebenso leicht Tippfehler in der letzten Kommandozeile verbessern.
Die Zuordnung von Tastenkombinationen zu bestimmten Editorfunktionen kann aber noch weiter Ihren speziellen Bedürfnissen angepaßt werden. Sie können jede Editorfunktion mit einer frei wählbaren Tastenkombination verknüpfen. Diese Um- bzw. Neubelegung der Tasten kann zur Laufzeit mit dem bind-Shellkommando durchgeführt werden.
Das Format einer Tastaturbelegung sieht folgendermaßen aus:Taste:Kommandobezeichnung
Die Kommandobezeichnungen sind in Klammern hinter den Beschreibungen der Editorfunktionen auf den vorhergehenden Seiten angegeben.
Für die Tastenkombinationen können die Konstruktionen `\C-' für die Kombination mit CONTROL und `\e-' oder `\M-' für die Metakombinationen mit ESC oder ALT verwendet werden. Außerdem können die folgenden Tasten benannt werden:
RUBOUT für Backspace
DEL für Delete
ESC für Escape
SPACE oder SPC für Leerzeichen
RETURN, RET, NEWLINE oder LFD für Zeilenende
TAB für Tabulator
$ bind -m emacs '"\C-xv":vi-editing-mode' $ bind -m vi '"\C-xe":emacs-editing-mode' $ bind -m vi-insert '"\C-xe":emacs-editing-mode' $ _Neben den Editorkommandos können auch Zeichenketten und Kommandokombinationen (Makros) auf bestimmte Tasten gelegt werden.
Beispielsweise können Sie mit dem folgenden Kommando ein Makro zum Editieren der PATH-Variablen im emacs-Modus installieren:
$ bind -m emacs '"\C-xp":"PATH=${PATH}\e\C-e\C-a\ef\C-f"'
$ _
Es ist auch möglich, eine neue Tastaturbelegung dauerhaft
einzurichten, indem die Zuordnung von Kommandos und
Tastenkombinationen in einer Datei
abgespeichert wird.Den Namen dieser Datei können Sie in der Shellvariablen INPUTRC festlegen. Wenn diese Variable nicht existiert, wird die Belegung aus der Datei ~/.inputrc gelesen.
Für jede Umbelegung muß eine Zeile in der Datei eingetragen werden. Format und Inhalt der Zeilen stimmen mit dem oben für bind beschriebenen überein.Zusätzlich können zur Anpassung von readline einige Schalter gesetzt und Variable belegt werden. Sie werden in der Form
set Schalter Wert
in der .inputrc-Datei eingetragen. Die Schalter können auch mit dem bind-Kommando benutzt werden. Die Werte in Klammern stellen die Voreinstellung dar.
Ähnlich wie beim C-Präprozessor können Teile der .inputrc-Datei durch die Direktiven $if, $else und $endif eingeschlossen werden, um diese Einstellungen nur unter bestimmten Bedingungen auszuführen. Folgende Tests sind vorgesehen:
$if Bash
# Umlaute in der Kommandozeile erlauben:
set convert-meta Off
set meta-flag On
set output-meta On
$if term=xterm
# Spezielle Einstellungen fuer xterm
$else
# Einstellungen fuer alle anderen Terminals
$endif
$if mode=vi
# Tastaturbelegung im vi-Modus
$endif
$if mode=emacs
# Tastaturbelegung im emacs-Modus
$endif
$endif
Eine ausführliche TEXinfo-Beschreibung aller readline-Funktionen kann mit dem info-Kommando nachgelesen werden.
Die aktuelle Tastaturbelegung wird mit dem Kommando `bind -v' ausgegeben.
Die Shell unterstützt die Eingabe solcher Kommandos, indem sie nach
einem Zeilenende in einer unvollständigen Kommandozeile eine neue
Eingabeaufforderung - in der Regel ein
> - ausgibt, bis der erwartete Abschluß des
begonnenen Kommandos eingegeben ist. Die so eingegebenen Teile werden
zusammen als eine Kommandozeile interpretiert.
Die Kommandozeile wird analysiert, indem sie anhand von ,,Trennzeichen`` in atomare Sinneinheiten (Wörter oder Token) geteilt wird. Dabei kann die gesamte Zeile in mehrere Kommandos zerfallen, die getrennt weiterverarbeitet werden.
Die Wörter der einzelnen Kommandos werden sequentiell (der Reihe nach) auf bestimmte Symbole oder Sonderzeichen durchsucht. Bestimmte Sonderzeichen führen zur Umlenkung der Ein- und Ausgabekanäle. Durch andere Symbole werden bestimmte Wörter verändert oder ersetzt. Dieser Vorgang wird als Parametersubstitution bezeichnet. Danach wird die Kommandozeile noch ,,aufgeräumt``. Abschließend werden die Programme (intern oder extern) lokalisiert und mit ihren Optionen und Argumenten aufgerufen.
Im Unterschied zur Bourne-Shell bietet die interaktive bash diese Möglichkeit normalerweise nicht auf der Kommandozeile (wohl aber beim source-Shellkommando). Durch das Kommando set -o interactive-comments kann die Verwendung von Kommentaren in der interaktiven Shell ermöglicht werden.
Auf der Kommandozeile (wie auch im Shellscript) werden Zeilen, die mit einem Doppelpunkt beginnen, zwar der Parametererweiterung unterworfen, sie werden aber nicht ausgeführt.
Ein häufiger Spezialfall tritt auf, wenn auf ein Kommentarzeichen in der ersten Zeile ein Ausrufezeichen folgt und auf dem Rest der ersten Zeile ein Interpreterprogramm benannt ist. Wenn so eine Textdatei ausführbar ist und anstelle eines Kommandos aufgerufen wird, übergibt der Linux-Kernel die Textdatei direkt dem benannten Interpreterprogramm, ohne extra eine Shell aufzurufen. Natürlich kann auch eine Shell als Interpreterprogramm für ein Shellscript benannt werden. Das folgende Script ersetzt beispielsweise die fehlende pwd-Funktion der tcsh:
#!/bin/bash IFS=" " builtin pwd
Jede Funktion und jedes Kommando kann eine einzige Zahl an die aufrufende Shell oder allgemeiner an das aufrufende Programm zurückgeben. Dieser Rückgabewert wird als Status bezeichnet.
Anders als z.B. in C-Funktionen gilt in der bash (wie auch in den anderen Shells) folgende Konvention:
In der Shell kann der Status des zuletzt ausgeführten Kommandos aus der Shellvariablen ? gelesen werden.
Häufig kann aus dem Statuswert auf die Art des Fehlers zurückgeschlossen werden. Wenn ein Kommando beispielsweise durch ein Signal beendet wurde, ist der Rückgabewert (Status) der Wert des Signals + 128.Der Status kann in sein logisches Gegenteil verkehrt werden (0 oder 1), indem dem gesamten Kommando ein `! ' vorangestellt wird. Um diese Konstruktion von der History-Substitution im C-Shell-Stil zu unterscheiden, muß dem Ausrufezeichen unmittelbar ein Blank oder `(' folgen.
Wie bei jeder anderen Programmiersprache gibt es für die Sprache zur Shellprogrammierung reservierte Wörter. Diese Wörter dürfen nicht für Variablennamen oder zum Benennen von Scriptfunktionen benutzt werden. Sie werden nur erkannt, wenn sie ohne Anführungszeichen und als erstes Wort eines einfachen Kommandos oder als drittes Wort eines case- oder for-Kommandos auftreten.
Folgende Wörter sind reserviert:
! case do done elif else esac
fi for function if in select then time until while { }
Die ,,Atome`` einer Kommandozeile - auch als Wörter oder Token bezeichnet - werden anhand bestimmter Trennzeichen identifiziert. Die einfachste und natürliche Trennung zweier Wörter findet durch Leerzeichen statt. Dabei ist die Anzahl der Trennzeichen gleichgültig. Anstelle von Leerzeichen können auch TABs benutzt werden. Wegen ihrer offenkundigen Ähnlichkeit werden diese Trenner auch als Blanks bezeichnet.
Die folgenden zur Shellprogrammierung verwendeten Sonderzeichen führen automatisch auch zur Trennung von Wörtern:
| & ; ( ) < > und das Zeilenende (RETURN)
Diese Zeichen haben in jedem Fall spezielle Aufgaben und können deshalb nicht einfach innerhalb von Argumenten an ein Kommando übergeben werden. Eine Reihe weiterer Zeichen werden nur in bestimmten Situationen als Operatoren erkannt. In diesen Fällen können auch sie nicht innerhalb von Argumenten an ein Kommando weitergegeben werden. Besondere Aufmerksamkeit ist bei den folgenden Zeichen geboten:
! * ? $ ` ' { } [ ] ^= # " \
Wenn eines der oben genannten (Sonder-) Zeichen als Argument an ein Kommando übergeben werden soll, muß es für die Shell ,,entwertet`` werden.
| & || && ; ;; ( )
Außer mit dem eigentlichen Kommandonamen (dem Namen der ausführbaren Datei) kann ein einfaches Kommando auch mit einer Zuweisung an eine Shellvariable beginnen.
Für jedes einfache Kommando können die offenen Datenkanäle umgeleitet, sowie neue erzeugt werden.
Es gibt drei Formen der Quotierung:
Das Fluchtsymbol ,,entwertet`` das unmittelbar folgende Sonderzeichen. Ein durch das Fluchtsymbol entwertetes Zeilenende wird ignoriert.
Die in Hochkommata eingeschlossenen Wörter werden von der Shell nicht weiter bearbeitet. Lediglich ein Hochkomma darf nicht in Hochkommata eingeschlossen werden; auch nicht wenn, es durch ein Fluchtsymbol eingeleitet wird.
Von den in Anführungszeichen eingeschlossenen Wörtern erkennt die Shell nur die Sonderzeichen $, ' und \ als solche. Alle anderen Wörter bleiben unbearbeitet. Das Fluchtsymbol behält seine Bedeutung aber nur, wenn es von einem der Zeichen $ ' " \ oder dem Zeilenende (RETURN) gefolgt wird. Ein Anführungszeichen darf zwischen zwei Anführungszeichen stehen, wenn es durch ein Fluchtsymbol eingeleitet wird.Die speziellen Parameter * und @ haben eine besondere Bedeutung, wenn sie zwischen Anführungszeichen auftauchen.
Von Anführungszeichen eingeschlossene Zeichenketten, denen ein Dollarzeichen vorangestellt ist, werden nach Möglichkeit dem aktuellen Locale entsprechend übersetzt. Wenn das aktuelle Locale C oder POSIX ist, wird das Dollarzeichen ignoriert. Die resultierende Zeichenkette bleibt in Anführungszeichen eingeschlossen.
Bevor eine Kommandozeile ausgeführt wird, können die bestehenden Eingabe- und Ausgabekanäle umgelenkt, sowie neue erzeugt werden. Auf diese Weise können Dateien im Dateisystem zum Lesen bzw. Schreiben für das Kommando geöffnet werden, die nach dessen Beendigung automatisch wieder geschlossen werden. Beispielsweise kann so die Ausgabe des ls-Kommandos zur weiteren Bearbeitung in eine Datei geschrieben werden.
Wenn mehrere Kanalumlenkungen in einer Kommandozeile auftauchen, werden sie der Reihe nach von links nach rechts ausgewertet.
Wenn in einer der folgenden Beschreibungen die Kanalnummer einer Datei nicht angegeben wird, so wird bei einer Eingabeumleitung die Standardeingabe (Kanal 0) und bei einer Ausgabeumleitung die Standardausgabe (Kanal 1) umgeleitet.
Das auf den Umleitungsoperator folgende Wort wird allen möglichen Parametererweiterungen unterworfen. Wenn durch die Erweiterung mehr als ein Wort entsteht, wird eine Fehlermeldung ausgegeben.Mit Hilfe des exec-Shellkommandos kann auch die Eingabe/Ausgabe der aktiven Shell umgelenkt werden, indem exec ohne Kommando, aber mit entsprechenden Umleitungen aufgerufen wird (siehe exec).
Wenn in einem Kommando mehrere Umleitungen gelegt werden, ist die Reihenfolge signifikant. Ein Beispiel hierfür ist bei der Verdoppelung der Dateikennung gegeben.
[n]<Wort
erzeugt entweder eine Eingabeumleitung von der mit dem (erweiterten) Wort bezeichneten Datei auf den Kanal mit der Nummer n, oder auf die Standardeingabe (Kanal 0), wenn keine Zahl n angegeben wird.
[n]>Wort
lenkt den Ausgabekanal mit der Nummer n auf die mit dem Wort bezeichnete Datei um. Wenn keine Zahl für die Kanalnummer angegeben ist, wird die Standardausgabe (Kanal 1) angenommen.
Wenn die angegebene Datei nicht existiert, wird sie erzeugt. Wenn eine Datei dieses Namens existiert, wird sie überschrieben, solange die Shelloption noclobber nicht gesetzt ist.
[n]>>Wort
öffnet die Datei mit dem angegebenen Namen zum Anhängen von Daten. Die Daten aus dem Ausgabekanal mit der Nummer n werden an die Datei angehängt. Wenn die Kanalnummer fehlt, wird die Standardausgabe umgelenkt.
Wenn die Datei nicht existiert, wird sie erzeugt.
&>Wort
oder
>&Wort
legt die Kanäle für die Standardausgabe und die Standardfehlerausgabe zusammen und schreibt sie in eine Datei namens Wort. Von den beiden Formen sollte die erste bevorzugt werden.
Diese Art der Kanalumlenkung wird benutzt, um einen Teil des Shellscripts direkt als Standardeingabe für ein Kommando zu benutzen. Es werden alle Zeilen des Dokumentes gelesen und als Eingabe an das Kommando weitergeleitet, bis eine Zeile auftaucht, die nur den Begrenzer enthält. Das in der ersten Zeile festgelegte Wort wird keiner Erweiterung unterzogen. Wenn es aber irgendeine Art der Quotierung enthält, ist der Begrenzer das Wort ohne die Quotierung. In diesem Fall wird aber das Dokument ohne jede Erweiterung an das Kommando weitergegeben. Anderenfalls (wenn das Wort keine Quotierung enthält) werden alle Parameter im Dokumenttext erweitert und es wird die Kommandosubstitution durchgeführt.
In dem zweiten Fall wird ein durch das Fluchtsymbol `\' eingeleitetes Zeilenende ignoriert. Um das Fluchtsymbol selbst sowie die Zeichen $ und ' im Dokument darstellen zu können, müssen sie ebenfalls durch ein Fluchtsymbol eingeleitet werden.
Wenn das optionale Minuszeichen bei der Einleitung des Shellscript-Dokumentes auftaucht, werden alle Leerzeichen und Tabulatoren am Anfang der Dokumentzeilen ignoriert. Dadurch kann das Dokument durch Einrückung deutlich von dem übrigen Shellscript abgesetzt werden, ohne daß diese Einrückung auch in der Ausgabe erscheint.
Wenn im Wort anstelle einer Zahl ein `-' steht, wird der Kanal n geschlossen. Wenn das Wort leer ist, wird es durch die Standardeingabe ersetzt.
[n]>&Wort
verdoppelt die Ausgabedateikennung in Wort. Wenn das Wort leer
ist, wird hier die Standardausgabe eingesetzt. Ansonsten ist die
Funktion die gleiche wie bei der Verdoppelung der Eingabekennung.
Ein Beispiel soll die Funktion der Verdoppelung verdeutlichen: Die Konstruktion
$ ls /usr/local/foo > inhalt 2>&1 $ cat inhalt ls: /usr/local/foo: No such file or directory $ _lenkt die Standardausgabe und die Standardfehlerausgabe in die Datei inhalt um.
Die Konstruktion
$ ls /usr/local/foo 2>&1 > inhalt ls: /usr/local/foo: No such file or directory $ cat inhalt $ _lenkt dagegen nur die Standardausgabe in die Datei inhalt um.
Beim ersten Beispiel wird zuerst die Standardausgabe in die Datei umgelenkt, danach wird der Standardausgabekanal verdoppelt und dabei die Standardfehlerausgabe ersetzt. Im zweiten Beispiel wird zuerst die Standardfehlerausgabe durch die Standardausgabe ersetzt. Das ist in diesem Moment aber noch der Bildschirm. Erst danach wird die Standardausgabe mit der Datei verbunden. Die Kopie des Standardausgabekanals (die Standardfehlerausgabe) wird von dieser Umlenkung aber nicht betroffen!
Die engste Verknüpfung mehrerer einfacher Kommandos wird durch eine sogenannte Pipeline hergestellt. Das Charakteristikum einer Pipeline ist die Zusammenlegung des Standardausgabekanals des einen Kommandos mit dem Standardeingabekanal des zweiten. Dabei wird die Multitasking-Fähigkeit von Linux ausgenutzt und die beiden (oder mehr) Kommandos als separate Prozesse gleichzeitig gestartet.
Die Syntax für die Zusammenfassung zweier Kommandos in einer Pipeline sieht folgendermaßen aus:
[time [-p]] [ ! ] Kommando |Kommando [ |Kommando] ...
Der entscheidende Kontrolloperator ist das Zeichen `|' (Pipe).
Seit der Version 2.0 benutzt die bash das zusätzliche Schlüsselwort time, das dazu dient, die Ausführungszeit der Pipeline zu ermitteln.
Der Status der gesamten Pipeline ist gleich dem Status des letzten Kommandos in der Pipeline (siehe status). Durch das Ausrufezeichen wird der Wahrheitswert des Status umgekehrt.Die Verknüpfung der Standardkanäle findet vor einer eventuellen Umlenkung durch eines der Kommandos statt. Das bedeutet, daß die Zusammenlegung von Standardfehlerausgabe und Standardausgabe tatsächlich in der Pipeline mündet.
Die parallele Ausführung aller einfachen Kommandos einer Pipeline legt es nahe, die komplette Pipeline syntaktisch als Einheit zu betrachten. Wenn im folgenden nicht ausdrücklich von einfachen Kommandos die Rede ist, steht ,,Kommando`` auch für Pipelines.
Es können mehrere Kommandos durch Pipelines verkettet werden. Dabei sind aber nur zwei Pipelines für jedes einfache Kommando erlaubt - jeweils eine für die Standardeingabe und die Standardausgabe. Soll ein Kommando aus mehreren Pipelines gleichzeitig lesen, kann das ab bash-1.13 durch die Prozeßsubstitution mit Named-Pipes realisiert werden.
Nachdem die Kommandozeile von der Shell bearbeitet ist, werden die darin enthaltenen Kommandos ausgeführt. Ein Kommando oder eine Pipeline wird dann zu einem Job. Dieser Job läuft weitgehend unabhängig von der Shell; trotzdem steht die Shell weiterhin mit allen Jobs in Verbindung und kann über Signale mit ihnen kommunizieren. Zu diesem Zweck unterhält die bash eine Tabelle aller aktuellen Jobs.
Wenn ein Job mit dem `&'-Zeichen im Hintergrund gestartet wird, gibt die bash eine Zeile mit der Jobnummer und der Prozeßnummer für diesen Job aus. Wenn ein Hintergrundjob beendet ist, wird wieder eine Meldung mit dem Namen, der Jobnummer und dem Status des Jobs ausgegeben.
Mit der Tastenkombination ^Z ist es jederzeit möglich, einen im Vordergrund laufenden Job anzuhalten. Es erscheint dann eine Meldung mit der Jobnummer und dem Namen des angehaltenen Jobs. Danach erscheint die Eingabeaufforderung der Shell.
Ein angehaltener Job kann mit dem bg- oder dem fg- Shellkommando im Hintergrund oder im Vordergrund gestartet werden. Mit dem kill-Kommando wird er abgebrochen (siehe bg, fg und kill).
Im Zusammenhang mit den genannten Kommandos kann ein Job mit seiner Jobspezifikation und seiner Prozeßnummer angesprochen werden.
Als Jobspezifikation werden die Jobnummer oder der Anfang des Jobnamens erkannt, indem sie durch ein Prozentzeichen `%' eingeleitet werden. Die Jobnummer ist die laufende Nummer, unter der der Job in der Jobtabelle geführt wird. Der zuletzt angehaltene Job wird auch als aktueller Job bezeichnet und kann mit `%+' angesprochen werden. Der zuvorletzt angehaltene Job wird auch als der letzte Job bezeichnet und kann mit `%-' benannt werden. Wenn ein angegebener Anfang auf mehrere Jobs paßt, wird eine Fehlermeldung ausgegeben. Ein Job kann auch einfach durch Angabe seiner Jobspezifikation (ohne Kommando) aus dem Hintergrund in den Vordergrund geholt werden. Zum Beispiel bringt `fg %1' den angehaltenen oder im Hintergrund laufenden Prozeß mit der Jobnummer 1 im Vordergrund zum Laufen.
Bei der Ausgabe der Jobtabelleneinträge wird der aktuelle Job mit einem `+' gekennzeichnet und der letzte Job mit einem `-'.
Wenn die Shell beendet werden soll, während sich angehaltene Jobs im Hintergrund befinden, wird eine Warnung ausgegeben und die Shell nicht beendet. Erst wenn die Shell entweder unmittelbar darauf, oder nach einem einzigen jobs-Shellkommando ein zweites Mal beendet wird, werden alle verbleibenden Jobs automatisch terminiert.
Wenn zum Zeitpunkt des Ausloggens noch Jobs im Hintergrund laufen, werden diese Jobs beim Verlassen der Shell automatisch an den init-Prozeß übereignet und laufen so weiter.
Neben der Möglichkeit, zwei oder mehr einfache Kommandos in einer Pipeline parallel aufzurufen, erlaubt die Shell weitere Aufrufe mehrerer Kommandos in einer einzigen Zeile. Diese Aufrufe werden als Listen bezeichnet.
Eine Folge von Kommandos kann durch die Kontrolloperatoren &&, ||, & oder ; zu einer Liste zusammengefaßt werden. Die Liste wird durch ein &, ; oder ein Zeilenende (RETURN) abgeschlossen.
Ein Semikolon kann zum Abschluß eines Kommandos benutzt werden. Auf diese Weise können beliebige Kommandos zu einer Liste zusammengefügt werden, indem sie, durch Semikolon getrennt, auf einer Zeile eingegeben werden. Die Ausführung der beiden Kommandos geschieht unabhängig, nacheinander.
Mit dem &-Operator wird ebenfalls ein Kommando abgeschlossen. Auch mit diesem Operator können also zwei Kommandos auf einer Zeile getrennt werden. Jedes mit einem & abgeschlossene Kommando wird unabhängig von den anderen Kommandos der gleichen Zeile im Hintergrund ausgeführt. Es können auf diese Weise also zwei oder mehr Kommandos parallel aufgerufen werden. Diese Kommandos stehen während der Ausführung nicht in Verbindung zueinander. Wenn alle Kommandos einer Zeile durch ein & abgeschlossen werden, erscheint bei der interaktiven Shell sofort die nächste Eingabeaufforderung.
Die Kontrolloperatoren && und || verknüpfen zwei Kommandos logisch miteinander. Das zweite Kommando dieser Liste wird in Abhängigkeit vom Ergebnis (Status) des ersten ausgeführt.
Bei der Verknüpfung durch
Kommando1 [ && Kommando2 ...]
wird das Kommando2 nur dann ausgeführt, wenn Kommando1 fehlerfrei abgeschlossen wurde. Man kann das als eine logische UND-Verknüpfung der beiden Kommandos betrachten. Der Status der UND-Liste ist wahr (Null), wenn beide Kommandos ,,wahr`` sind. Wenn bereits das erste Kommando Null liefert, wird das zweite zur Bewertung des Gesamtausdrucks nicht mehr benötigt, also wird es auch nicht ausgeführt.
Das Pendant zur UND-Liste ist die ODER-Verknüpfung durch
Kommando1 [ ||Kommando2 ...]
Hier wird das Kommando2 nur dann ausgeführt, wenn bei der
Bearbeitung vom Kommando1 ein Fehler aufgetreten ist.
Analog zur UND-Verknüpfung kann auch die Verkettung durch
|| als logische ODER-Verknüpfung betrachtet werden.
Der Status der ODER-Liste ist wahr, wenn das erste oder
das zweite Kommando einen Status Null liefert. Wenn das bereits beim
ersten Kommando erfüllt ist, wird das zweite nicht mehr
ausgeführt.
Einzelne Kommandos oder Listen können auf verschiedene Weisen weiter zu Gruppen zusammengefaßt werden:
Die Operatoren zur Shellprogrammierung unterscheiden sich in Rang und Assoziativität. Prinzipiell wird eine Kommandozeile von links nach rechts abgearbeitet. Die Zusammenfassung in UND- oder ODER-Listen hat gegenüber der Auflistung mit Semikolon oder & Vorrang. Die Zusammenfassung einfacher Kommandos in Pipelines hat wiederum größere Assoziativität als die Listen. Die beiden Zeilen
{ cat /etc/gettydefs || cat /etc/gettytab; }| grep 38400
cat /etc/gettydefs || cat /etc/gettytab | grep 38400
unterscheiden sich syntaktisch nur in der Klammerung, die größere
Assoziativität der Pipeline führt in der zweiten Zeile aber zu einer
impliziten Klammerung der beiden letzten Kommandos. Die erste Zeile
schreibt die erste existierende der beiden angegebenen Dateien in
den Standardausgabekanal, der durch eine Pipeline dem
grep-Kommando zur Auswertung übergeben wird.
Die zweite Zeile schreibt entweder die Datei /etc/gettydefs
auf den Bildschirm (Standardausgabe), oder sie übergibt die Datei
/etc/gettytab dem grep-Kommando.
Die geschweiften Klammern trennen selbst keine Kommandos (siehe oben). Aus diesem Grund ist ein Leerzeichen zwischen der einleitenden Klammer und dem ersten Kommando der eingeschlossenen Liste notwendig. Um die Trennung zum ersten Kommando nach der abschließenden Klammer eindeutig anzugeben, ist es sinnvoll, die eingeklammerte Liste immer mit einem Semikolon abzuschließen. Im Gegensatz zur Bourne-Shell wird in dem Beispiel oben das Kommando korrekt interpretiert, wenn das Semikolon weggelassen wird, weil die der Klammer folgende Pipeline die Kommandos trennt.Im Unterschied zur Bourne-Shell wird bei der bash auch in dem Beispiel oder bei einer Ausgabeumlenkung für die komplette Klammer keine Subshell erzeugt.
cd / $ (cd /usr/bin; ls e*); ls -F egrep elvis elvprsv elvrec env ex expand bin/ etc/ lost+found/ root/ usr/ boot/ home/ mnt/ sbin/ var/ dev/ lib/ proc/ tmp/ vmlinuz $ _erzeugt eine Subshell, in der aus dem aktuellen Wurzelverzeichnis in das Verzeichnis /usr/bin gewechselt wird. Hier können beispielsweise alle Dateien angezeigt werden, deren Name mit einem `e' beginnt. Mit den schließenden Klammern wird auch die Subshell beendet. Das darauffolgende Listing findet wieder im ursprünglich aktuellen Verzeichnis statt.
Die Werte werden normalerweise nach dem Schlüsselwort in übergeben. Dazu können mehrere Wörter angegeben werden, die von der Shell erweitert werden. Für jeden Durchlauf wird ein Token in der Variablen Name übergeben.
Wenn der `in Wort' Teil fehlt, wird die Liste für jeden gesetzten Positionsparameter einmal ausgeführt.
Die interaktive Eingabe einer for-Schleife wird (wie die Eingabe jedes anderen aus mehreren Teilen bestehenden Konstrukts) von der Shell unterstützt, indem sie einen sekundären Prompt (PS2) zur Eingabe einer Schleife über mehrere Zeilen anbietet. Dieser sekundäre Prompt wird ausgegeben, solange die Schleife nicht mit done abgeschlossen ist.
Als Status wird der Rückgabewert des letzten ausgeführten Kommandos zurückgegeben. Wenn kein Kommando ausgeführt wurde, ist der Status Null.
In dem folgenden Beispiel werden im aktuellen Verzeichnis alle Dateien mit der Endung `foo' umbenannt, so daß sie auf `bar' enden.
$ for i in *.foo; do > base=`basename $i .foo` > mv $i $base.bar > done $ _Die Zuweisung der Ausgabe vom Shellutility basename an die Variable base findet durch ,,Kommandosubstitution`` statt. Diese Operation wird durch die ,,Backquotes`` ausgelöst, nicht durch Hochkomma.
Die bash bietet mit ihrer Parametererweiterung eine andere
schöne Methode, die Endung vom Dateinamen zu trennen: mit der
Konstruktion base=${i%.foo}
(Parametererweiterung). Das spart den Aufruf eines externen
Kommandos und verbessert damit die Performance.
Wenn eine Variable innerhalb einer for-Schleife verändert wird, ist der neue Wert auch außerhalb der Schleife sichtbar. Die bash verhält sich damit POSIX-1003.2-konform. Eine Ausnahme kann für die Zählvariable erreicht werden, indem das Kommando set -l gegeben wird. In diesem Fall wird die Zählvariable nach dem letzten Durchlauf auf den Wert vor Beginn der Schleife zurückgesetzt.
Bei der interaktiven Eingabe einer while-Schleife wird so lange der sekundäre Prompt (PS2) ausgegeben, bis die Schleife mit done abgeschlossen ist.
Der Status der while-Schleife ist gleich dem Status des letzten Kommandos des `do-Teils' oder Null, wenn kein Kommando ausgeführt wurde.
Im folgenden Beispiel wird die while-Schleife benutzt, um die Unterverzeichnisse z. B. des Verzeichnisses /usr/local/man anzulegen.
$ declare -i zahl=1 $ while [ $zahl -lt 10 ] > do > mkdir man$zahl > mkdir cat$zahl > zahl=$((zahl+1)) > done $ _Die Deklaration von zahl als Integer-Variable ist an dieser Stelle nicht notwendig, weil die Zuweisung einer Zahl und die Verwendung in arithmetischen Ausdrücken diese Interpretation implizieren.
Zur Inkrementierung der Zählvariablen wird die Arithmetische Erweiterung benutzt, die hier beschrieben ist. Die bash erlaubt ab Version 1.13 auch die direkte Inkrementierung einer Integer-Variablen durch den `+=' Zuweisungsoperator in einer arithmetischen Erweiterung oder mit dem let-Shellkommando. Beide Varianten sind in der Standard-Bourne-Shell nicht vorgesehen.
Mit der optionalen elif-Konstruktion können beliebig lange if-else-Ketten erzeugt werden. Wenn der `elif Liste'-Teil des letzten elif nicht Null liefert, wird der abschließende else-Teil bearbeitet.
Wie bei den Schleifen wird auch bei der interaktiven Eingabe einer if-Anweisung der sekundäre Prompt ausgegeben, bis die Konstruktion mit einem fi abgeschlossen ist.
Der Status der gesamten if-Konstruktion ist gleich dem Status des zuletzt ausgeführten Kommandos, oder Null, wenn kein Kommando ausgeführt wurde.
Das folgende Beispiel zeigt, wie in der Initialisierungsdatei ~/.bashrc zwischen einer Shell im xterm und den Textbildschirmen unterschieden werden kann.
if [ $WINDOWID ]; then TERM=xterm export XDVIFONTS=/usr/TeX/lib/tex/fonts/%f.%d%p export OPENWINHOME=/usr/openwin export PAGER=/usr/X386/bin/xless else export PAGER=/usr/bin/less fiEin weiteres Beispiel zeigt, wie in einem Shellscript unterschieden werden kann, ob die aufrufende Shell interaktiv arbeitet oder nicht.
if [ "${-#*i}" = "$-" ]; then
echo Die Shell arbeitet nicht interaktiv
else
echo Die Shell arbeitet interaktiv
fi
Der in diesem Beispiel benutzte Ausdruck
["${-#*i}" = "$-" ] ist ein schönes Beispiel für die
Parametererweiterung, wie sie hier erklärt ist. Im Spezialparameter - sind
die Optionsflags der Shell gespeichert. Durch die ,,Erweiterung``
${-#*i} wird aus dieser Zeichenkette ein `i' (und
alle Zeichen davor) entfernt, wenn es enthalten ist. Der
umschließende test vergleicht die so eventuell verkürzte
Zeichenkette mit dem Original. Wenn sie gleich sind, ist die
`i'-Option der interaktiven Shell nicht
gesetzt.
Die Anführungszeichen sind in dem Beispiel notwendig, weil die Shellvariable `-' auch leer sein kann. In diesem Fall würde sie ohne die Anführungszeichen aus der Kommandozeile entfernt, was in dem Vergleich zu einem verdeckten Syntaxfehler und einem falschen Ergebnis des Tests führen könnte.
Das case Wort wird von der bash erweitert, dann wird die daraus entstandene Zeichenkette mit den Mustern verglichen und bei Übereinstimmung die Liste von Kommandos ausgeführt. In den Suchmustern können reguläre Ausdrücke wie bei der Pfadnamenerweiterung (z. B. `*' und `?') verwendet werden.
Wenn ein übereinstimmendes Muster gefunden wurde, wird die case-Anweisung beendet und nicht nach weiteren Übereinstimmungen gesucht.
Der Status ist Null, wenn keine Übereinstimmung gefunden wurde. Sonst wird der Status des zuletzt ausgeführten Kommandos der Liste übergeben.
Das dem letzten Beispiel zugrunde liegende Problem kann auch mit der case-Anweisung gelöst werden. Diese Lösung ist zwar kein typisches Beispiel für eine Vielfachverzweigung, sie bietet sich aber wegen der Auswertung regulärer Ausdrücke durch case in der Praxis eher an als das oben gegebene Beispiel.
case $- in
*i\*) echo hier sollte nach der Zeichenkette 'i*'
echo gesucht werden.
echo *****FEHLER***** in der bash-1.12.;;
*i*) echo Die Shell arbeitet interaktiv.;;
*) echo Die Shell arbeitet nicht interaktiv.;;
esac
In der bash Version 1.12 konnte mit der
case-Anweisung nicht nach regulären
Ausdrücken selbst gesucht werden, die Quotierung der Wildcards
wurde ignoriert. Ab Version 1.13 ist dieser Fehler behoben.
Der in Wort-Teil wird erweitert und die so generierten Wörter als numerierte Liste (Menü) auf dem Standardfehlerkanal ausgegeben. Mit dem PS3-Prompt wird daraufhin eine Eingabe von der Tastatur gelesen. Eine leere Eingabe führt zu einer erneuten Anzeige des Menüs.
Wenn ein Wort aus der Liste durch seine Nummer bestimmt wird, führt die bash die Kommandos der do Liste aus und stellt dabei das ausgewählte Wort in der Variablen Name zur Verfügung. Wird in der Eingabezeile keine passende Zahl übergeben, ist Name leer, die Eingabezeile ist aber in der Variablen REPLY gespeichert.
Menüteil und Ausführung der Liste werden so lange wiederholt, bis die Schleife mit break oder return verlassen wird. Es ist möglich, mit CONTROL-D das Menü unmittelbar zu verlassen.
Wenn der in Wort-Teil fehlt, werden stattdessen die Positionsparameter verwendet.
Scriptfunktionen sind Teile eines Shellscripts oder einer Initialisierungsdatei für eine interaktive Shell, die komplett in der Shellumgebung gespeichert werden. Wenn ein Kommando in der Kommandozeile mit einer solchen Funktion übereinstimmt, wird die unter dem Funktionsnamen gespeicherte Liste von Kommandos ausgeführt. Es wird dazu kein neuer Prozeß erzeugt.
Im Unterschied zu alias-Synonymen können Scriptfunktionen Argumente verarbeiten. Wenn die Scriptfunktion mit Argumenten aufgerufen wird, werden diese Argumente der Funktion als Positionsparameter übergeben. Der Spezialparameter `#' wird aktualisiert. Der Positionsparameter `0' bleibt allerdings unverändert.
Mit dem local-Shellkommando ist es möglich, lokale Variablen für Scriptfunktionen zu erzeugen. Normale Shellvariablen sind ,,global``, sind also in der gesamten Shell uneingeschränkt sichtbar.
Wenn in einer Scriptfunktion das Shellkommando return auftaucht, wird die Funktion beendet und mit der dem Aufruf folgenden Zeile des Shellscripts oder der interaktiven Eingabe fortgesetzt. Die Positionsparameter und der Spezialparameter `#' werden auf ihre Werte vor dem Funktionsaufruf zurückgesetzt.
Eine Liste der definierten Scriptfunktionen erhält man in einer interaktiven Shell mit der Option `-f' zu den Shellkommandos declare oder typeset. Die Scriptfunktionen werden nur dann an alle Untershells weitergereicht (und stehen nur dann auch in diesen Shells zur Verfügung), wenn sie mit der Shellfunktion export unter der Option `-f' für den Export bestimmt wurden.
Scriptfunktionen können rekursiv aufgerufen werden. Es gibt keine Begrenzung für die Anzahl der rekursiven Aufrufe.
Aus dem Blickwinkel des Shellprogrammierers ist die zentrale Rolle von Variablen unmittelbar klar. Variable sind symbolische Namen für Platzhalter, in denen Werte (Zahlen oder Zeichenketten) gespeichert werden können.
Eine Variable kann durch eine Zuweisung der folgenden Form erzeugt werden:
Name=[Wert]
Als Namen für Variable kommen beliebige alphanumerische (ASCII-) Zeichenketten in Frage, die mit einem Buchstaben beginnen. Der Unterstrich `_' wird zu den erlaubten Buchstaben gerechnet.
Zwischen den Bestandteilen der Zuweisung dürfen keine Leerzeichen stehen.
Wenn kein Wert angegeben ist, wird der Variablen die leere Zeichenkette (Nullstring) zugewiesen.
Es ist nicht notwendig (aber möglich), Variable zu deklarieren. Automatisch erzeugte Variable speichern alle ihnen zugewiesenen Werte als Zeichenketten. Die Interpretation des Inhalts einer Variablen erfolgt ,,aus dem Zusammenhang``. Das heißt, in arithmetischen Ausdrücken werden Ziffernfolgen automatisch als Zahlen interpretiert. Durch ausdrückliche Deklaration einer Variablen als Integer (mit der Shellfunktion declare -i) wird erreicht, daß jede Zuweisung automatisch der arithmetischen Erweiterung unterworfen wird. Damit ist garantiert, daß eine solche Variable nach ihrer Initialisierung immer Zahlen enthält.Der Zugriff auf den Wert eines Parameters bzw. die Übergabe eines Parameters erfolgt durch den Operator `$' gefolgt von der Parameterbezeichnung.
Ein Parameter gilt als gesetzt, wenn ihm ein Wert zugewiesen wurde. Eine leere Zuweisung - der Nullstring ' ' - gilt als Wert in diesem Sinne. Wenn eine Variable gesetzt ist, kann sie nur durch das unset-Kommando entfernt werden.
Auf der Benutzerebene können Umgebungsvariable wie Shellvariable beliebig erzeugt, gelesen und verändert werden. Deshalb erscheinen die Umgebungsvariablen als eine Untermenge der Shellvariablen. Umgebungsvariable können mit dem printenv-Kommando oder dem export-Shellkommando angezeigt werden. Sämtliche definierten Shellvariablen werden mit dem set-Shellkommando ausgegeben.
Die folgenden Variablen werden von der Shell ausgewertet. In einigen Fällen wird die Variable mit einem Standardwert initialisiert.
^ vorbelegt.
Das optionale dritte Zeichen kennzeichnet
einen Kommentar im Historykommando. Wenn es als erstes Zeichen eines
Wortes auftaucht wird der Rest der Zeile bei der
History-Erweiterung ignoriert. Das bedeutet nicht unbedingt, daß
die Shell bei der weiteren Interpretation den Zeilenrest als
Kommentar erkennt.
Wenn die Variable leer ist oder keine Zahl enthält, so ist die Voreinstellung 10. Wenn die Variable nicht gesetzt ist, führt jedes EOF-Zeichen sofort zum Verlassen der Shell.
Dieser Schalter funktioniert nur, wenn die Mailbox in einem Verzeichnis liegt, dessen Dateisystem die Zugriffszeit verwaltet (nicht Minix oder Extended1). In der Version 2.0 wird dieser Schalter nicht unterstützt.
Ein einzelner Punkt anstelle des Wurzelverzeichnisses steht für das aktuelle Verzeichnis. Eine Tilde `~' steht für das Heimatverzeichnis des Anwenders.
Der Standardpfad zu den ausführbaren Dateien eines Linux-Systems ist:
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/X11R6/bin:/usr/local/bin
Die Verzeichnisse sbin können für User ohne Systemverwaltungsaufgaben auch entfallen. Bei Installationen ohne X Window System kann das Verzeichnis /usr/X11R6/bin ebenfalls weggelassen werden. Durch die Installation zusätzlicher Software können Erweiterungen des Pfades um Verzeichnisse wie /usr/opt/bin oder /home/postgres/bin notwendig werden.
Die PATH-Variable wird in der Regel von der Systemverwalterin in der Datei /etc/profile für alle Login-Shells gemeinsam auf einen bestimmten Wert gesetzt. Dieser Wert kann vom Benutzer beliebig verändert werden. Die PATH- Variable kann nicht mit dem unset-Shellkommando gelöscht werden.
Aus Gründen der Systemsicherheit ist es sinnvoll, das aktuelle Verzeichnis (bezeichnet durch einen Punkt) nur als letztes der zu durchsuchenden Verzeichnisse anzugeben. Anderenfalls könnte ein Standardprogramm aus dem Systempfad versehentlich mit einem gleichnamigen Kommando im aktuellen Verzeichnis verwechselt werden.
Der optionale Buchstabe l in der Formatangabe veranlaßt die Ausgabe eines längeren Formates, in dem auch die Minuten enthalten sind.
Zeilenvorschübe im Formatstring können durch die Tastenfolge ^-V ^-J erzeugt werden.
Die folgenden Variablen werden automatisch durch die Shell gesetzt. Die meisten können vom Benutzer nicht verändert direkt werden.
Seit Version 2.0 unterstützt die bash eindimensionale, (nichtnegativ) numerisch indizierte Arrays. Die einzelnen Felder eines Arrays entstehen wie einfache Variable durch Zuweisung eines Wertes. Eine Deklaration und Typisierung ist möglich, aber nicht notwendig. Es gibt keine Beschränkung für die Länge eines Arrays.
Die Initialisierung eines Arrays kann durch die Zuweisung einer einzigen Liste erfolgen. Die Indizierung beginnt mit 0. Wenn bei der Initialisierung der Index nicht angegeben ist, wird automatisch der auf den höchsten bereits definerten Index folgende Wert belegt.
Bei der Verwendung von Array-Feldern muß der Bezeichner in geschweiften Klammern eingeschlossen werden, damit er von einfachen Variablen unterschieden werden kann. Die Symbole @ und * indizieren das gesamte Array. Bei der ersten Form wird immer eine Liste aller Arrayeinträge geliefert. Die zweite Form liefert eine einzige Zeichenkette mit allen Einträgen, wenn sie in Anführungszeichen eingeschlossen wird.
Das folgende Beispiel zeigt die Verwendung einer Array-Variablen:
$ farben=(BLACK RED GREEN [4]=BLUE MAGENTA CYAN WHITE)
$ echo ${farben[5]}
MAGENTA
$ farben[3]=YELLOW
$ echo ${#farben[1]}
3
$ echo ${#farben[@]}
8
$ for i in ${farben[*]}; do echo $i; done
BLACK
RED
GREEN
YELLOW
BLUE
MAGENTA
CYAN
WHITE
$ for i in "${farben[*]}"; do echo $i; done
BLACK RED GREEN YELLOW BLUE MAGENTA CYAN WHITE
$
Wenn ein Positionsparameter mit mehr als einer Stelle (>9) bezeichnet werden soll, muß er in geschweifte Klammern gesetzt werden: z.B. ${12}.
Nur durch Klammererweiterung, Worttrennung oder Pfadnamenerweiterung können neue Wörter in der Kommandozeile entstehen. Die Ergebnisse aller anderen Erweiterungen werden als einzelne Wörter interpretiert. Einzige Ausnahme ist der Spezialparameter `$@', dessen Inhalt ungeachtet von Blanks als einziges Wort behandelt wird.
Die dem Beispiel zur for-Schleife zugrunde liegende Aufgabe kann durch Klammererweiterung auf einer einzigen Kommandozeile formuliert werden:
$ mkdir /usr/local/man/{man,cat}{1,2,3,4,5,6,7,8,9,n,l}
$ _
Dieses Beispiel zeigt, daß im Unterschied zur Pfadnamenerweiterung hier auch neue Dateinamen erzeugt werden können.
Die Klammererweiterung wird vor allen anderen Ersetzungsoperationen durchgeführt. Es handelt sich um eine reine Textoperation, es werden keine Zeichen aus den Bausteinen verändert. Das geschieht erst in den darauf folgenden Schritten.
Mit dieser Behandlung geschweifter Klammern verhält sich die bash absichtlich anders als die Bourne-Shell, die solche Zeichen als Teil von Wörtern nicht verändert. Um die Kompatibilität zur sh wiederherzustellen, kann die Klammererweiterung durch eine Änderung der entsprechenden set-Option durch das Kommando set +o braceexpand abgeschaltet werden.