next up previous contents index
Next: cat Up: Von GNU's, Muscheln und Previous: basename

Subsections


bash

    

Funktion

bash - die Wiedergeburtsmuschel. Stark entwickelter Nachfahre eines unsterblichen Wesens aus dem Unix (Kreidezeit).

Syntax

bash [Optionen] [Datei]

Beschreibung

In der Computersteinzeit wurden Programme in Lochkarten gestanzt und zusammen mit den Daten in mechanische Kartenleser gepackt. Die Auswahl zwischen den möglichen Programmen fand also nicht an einer Systemconsole, sondern vor den Regalen des Kartenarchivs statt. Heute sind die Programme und die Daten auf magnetischen Datenträgern gespeichert. Die Festplatte einer durchschnittlichen Linux-Installation bietet mindestens 300 verschiedene Programme zur Auswahl.

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.

Interaktive Shell und Shellprogrammierung

 

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.

Der Kommandozeileneditor

   Alle Tastatureingaben, die zeilenweise erfolgen, können mit bestimmten Steuerzeichen ,,editiert`` werden. Mit dem Steuerzeichen CONTROL-U wird normalerweise die komplette Zeile gelöscht, CONTROL-C bricht die Eingabe ab, CONTROL-D[*] steht für das Dateiende (EOF, End Of File), also für das Ende der interaktiven Eingabe insgesamt, CONTROL-H oder BACKSPACE löscht das letzte Zeichen.

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

Zeilenanfang (C-a)
setzt die Einfügemarke an den Anfang der Kommandozeile.
(beginning-of-line)
Zeilenende (C-e)
setzt die Einfügemarke an das Ende der Kommandozeile. (end-of-line)
Zeichen vorwärts (C-f)
setzt die Einfügemarke ein Zeichen nach rechts. Diese Funktion ist auch mit der rechten Pfeiltaste im Cursorblock erreichbar. (forward-char)
Zeichen rückwärts (C-b)
setzt die Einfügemarke ein Zeichen nach links. Diese Funktion ist auch mit der linken Pfeiltaste im Cursorblock erreichbar. (backward-char)
Wort vorwärts (M-f)
setzt die Einfügemarke an das Ende des aktuellen Wortes oder ein Wort weiter (wenn die Einfügemarke zwischen zwei Wörtern steht). (forward-word)
Wort rückwärts (M-b)
setzt die Einfügemarke an den Anfang des aktuellen Wortes oder des vorhergehenden Wortes (wenn die Einfügemarke zwischen zwei Wörtern steht). (backward-word)
Bildschirm löschen (C-l)
löscht alle Zeichen vom Bildschirm. Die Einfügemarke erscheint danach auf der ersten Zeile. (clear-screen)

Automatische Erweiterung von Kommando- und Dateinamen 

erweitern (TAB)
  versucht die bis zu diesem Editorbefehl geschriebene Kommandozeile sinnvoll zu ergänzen. Das geschieht, indem die Zeichenfolge des letzten Wortes bis zur Einfügemarke mit den Namen von Kommandos, Dateien und Verzeichnissen verglichen und das Wort so weit ergänzt wird, wie eine eindeutige Zuordnung möglich ist. Das erste Wort eines einfachen Kommandos wird dabei nur mit den Kommandonamen in den PATH-Verzeichnissen verglichen, die   weiteren Wörter eines einfachen Kommandos werden dagegen nur noch mit Datei- und Verzeichnisnamen im aktuellen Verzeichnis (Arbeitsverzeichnis) verglichen. In einigen Fällen (z. B. bei Pipelines) werden auch die ersten Wörter der folgenden Kommandos auf diese Weise richtig zugeordnet.

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)

mögliche Erweiterungen (M-?)
zeigt alle als sinnvoll erkannten Erweiterungen an. Als sinnvoll gilt hier wieder ein Kommandoname als erstes Wort eines einfachen Kommandos und ein Datei- oder Verzeichnisname für jedes weitere Wort. (possible-completions)
nur Kommandoerweiterung (M-!)
versucht, das Wort vor dem Cursor zu einem Kommandonamen zu erweitern. (complete-command)
mögliche Kommandoerweiterungen (C-x !)
gibt eine Liste aller als mögliche Erweiterungen für das Wort vor der Einfügemarke in Frage kommenden Kommandonamen aus. (possible-command-completions)
nur Dateinamenerweiterung (M-/)
vergleicht das Wort bis zum Cursor nur mit Datei- und Verzeichnisnamen. Werden passende Namen gefunden, findet eine Erweiterung wie beim TAB- Editorkommando statt. (complete-filename)
mögliche Dateinamen (C-x /)
zeigt alle als sinnvoll erkannten Datei- und Verzeichnisnamen, ohne eine Erweiterung auszuführen. (possible-filename-completions)
Benutzernamenerweiterung (M-~)
versucht, das Wort bis zur Einfügemarke zu einem Benutzernamen zu erweitern. (complete-username)
mögliche Benutzernamen (C-x ~)
zeigt alle möglichen Benutzernamen, auf die das Wort bis zur Einfügemarke paßt. (possible-username-completions)
Variablenerweiterung (M-$)
versucht, das Wort bis zur Einfügemarke zu einem Variablennamen zu erweitern. (complete-variable)
mögliche Variable (C-x $)
zeigt alle möglichen Variablennamen an, auf die das Wort bis zur Einfügemarke paßt. (possible-variable-completion)
nur Hostnamenerweiterung (M-@)
erweitert das Wort unter der Einfügemarke zu einem Hostnamen. Dieser Name wird aus der Datei /etc/hosts genommen, wenn in der Shellvariablen hostname_completion_file keine andere Datei angegeben ist. (complete-hostname)
mögliche Hostnamen (C-x @)
zeigt alle möglichen Erweiterungen für den Hostnamen. (possible-hostname-completions)
Erweiterung aus der History (M-TAB)
versucht, das Wort vor dem Cursor aus dem Historyspeicher zu ergänzen. (dynamic-complete-history)
Erweiterung in Klammern (M-{)
schließt die Liste der möglichen Dateinamenerweiterungen in Klammern ein, so daß die Shell sie zu einer Liste dieser Namen erweitern kann. (complete-into-braces)
Änderungen des Textes
Zeichen löschen (C-d)
löscht das Zeichen unter dem Cursor. Wenn CONTROL-d als erstes Zeichen einer leeren Kommandozeile eingegeben wird, erzeugt diese Tastenkombination ein EOF-Zeichen für das Ende der interaktiven Eingabe.[*] (delete-char)
letztes Zeichen löschen (BACKSPACE)
löscht das Zeichen vor dem Cursor. (backward-delete-char)
wörtlich einfügen (C-q, C-v)
wird benutzt um CONTROL-Zeichen in die Kommandozeile zu schreiben, die normalerweise durch den Editor abgefangen und bearbeitet werden. (quoted-insert)
Tabulator einfügen (M-TAB)
schreibt ein TAB in die Kommandozeile. (tab-insert)
Text einfügen (a, b, A, 1, ?, ...)
schreibt die Tastatursymbole (Buchstaben) in die Kommandozeile, wie sie von der Tastatur gelesen werden. Hinter dieser etwas verklausulierten Formulierung verbirgt sich die Eingabe eines normalen Buchstabens. (self-insert)
zwei Zeichen vertauschen (C-t)
vertauscht das Zeichen vor der Einfügemarke mit dem Zeichen unter der Einfügemarke. Die Einfügemarke wandert außerdem um eine Stelle weiter. Wenn die Einfügemarke am Zeilenende angekommen ist, werden die beiden Zeichen vor der Einfügemarke vertauscht. (transpose-chars)
zwei Wörter vertauschen (M-t)
vertauscht das Wort unter der Einfügemarke mit dem Wort vor der Einfügemarke bzw. das Wort nach der Einfügemarke mit dem Wort vor der Einfügemarke. Die Einfügemarke steht danach hinter dem letzten der vertauschten Wörter. Wenn die Einfügemarke bereits am Ende der Kommandozeile steht, werden die beiden Wörter vor der Einfügemarke vertauscht. (transpose-words)
GROSSBUCHSTABEN (M-u)
wandelt alle Buchstaben des Wortes von der Einfügemarke an in Großbuchstaben um. (upcase-word)
kleinbuchstaben (M-l)
wandelt alle Buchstaben des Wortes von der Einfügemarke an in Kleinbuchstaben um. (downcase-word)
Großschreibung (M-c)
wandelt den Buchstaben unter der Einfügemarke oder den ersten Buchstaben des folgenden Wortes in Großbuchstaben um, die folgenden Buchstaben bis zum Wortende alle in Kleinbuchstaben. Anschließend steht die Einfügemarke hinter dem umgewandelten Wort. (capitalize-word)
Ausschneiden und Einfügen
bis zum Zeilenende ausschneiden (C-k)
löscht die restliche Kommandozeile von der Einfügemarke an und speichert sie im Ausschneide-Ringspeicher. (kill-line)
vom Zeilenanfang ausschneiden (normalerweise ohne Belegung)
schneidet den Anfang der Kommandozeile bis zur Einfügemarke aus. Dieses Kommando ist normalerweise nicht mit einer Tastenkombination verbunden. (backward-kill-line)
Rest des Wortes ausschneiden (M-d)
schneidet von der Einfügemarke an ein Wort aus und speichert es im Ringspeicher. Als Wort werden hier alle Zeichen von der Einfügemarke an bis zum nächsten Sonderzeichen betrachtet. Eine beliebig lange Folge von Sonderzeichen unter oder unmittelbar nach der Einfügemarke wird nicht als Worttrenner behandelt. (kill-word)
Anfang des Wortes ausschneiden (M-BACKSPACE)
schneidet alle Zeichen vor der Einfügemarke bis zum nächsten Sonderzeichen aus und speichert sie im Ringspeicher. Das Zeichen unter der Einfügemarke wird nicht ausgeschnitten. Eine beliebig lange Folge von Sonderzeichen unmittelbar vor der Einfügemarke wird nicht als Worttrenner behandelt. (backward-kill-word)

vom Zeilenanfang bis zur Einfügemarke ausschneiden (C-u)
schneidet den Anfang der Kommandozeile bis zur Einfügemarke aus und speichert ihn im Ringspeicher. Das Zeichen unter der Einfügemarke wird nicht ausgeschnitten. (unix-line-discard)
Anfang des Wortes ausschneiden (C-w)
schneidet alle Zeichen vor der Einfügemarke bis zum nächsten Leerzeichen aus und speichert sie im Ringspeicher. (unix-word-rubout)
ausgeschnittenes Stück einfügen (C-y)
fügt das zuletzt in den Ausschneide-Ringspeicher geschriebene Stück vor der Einfügemarke ein. Das Stück wird dabei aus dem Ringspeicher entfernt. (yank)
Ausschneide-Ringspeicher rotieren (M-y)
ersetzt das zuletzt eingefügte Stück durch das vor diesem Stück in den Ringspeicher eingefügte Stück der Kommandozeile. Das zuvor ersetzte Stück wird wieder in den Ringspeicher eingefügt, das aktuell ersetzte Stück daraus entfernt. (yank-pop)
Argumente
numerisches Argument (M-0, M-1, ... , M--)
wird als numerisches Argument für das folgende Editorkommando benutzt. In der Regel wird durch dieses Argument die Anzahl der Wiederholungen dieses Editorkommandos bestimmt. (digit-argument)
universelles Argument (nicht Belegt)
entspricht dem gleichnamigen Tastaturbefehl vom emacs-Editor. Es ist allerdings keiner Tastenkombination zugeordnet. (universal-argument)

Verschiedenes

einlesen der Initdatei (C-x C-r)
veranlaßt die Shell, die .inputrc-Datei neu einzulesen. (re-read-init-file)
Metazeichen (ESC)
veranlaßt die Shell, das nächste Zeichen als Metazeichen zu interpretieren. Wichtig, wenn keine Metataste auf der Tastatur ausgewiesen ist: bei einer PC-Tastatur ist meist die linke ALT-Taste mit der Metafunktion belegt! (prefix-meta)
Kommando zurück (C-_)
nimmt das zuletzt ausgeführte Editorkommando zurück. Es werden alle für eine Kommandozeile gegebenen Editorkommandos gespeichert und sind auf diese Weise nacheinander reversibel. (undo)
alles zurück (M-r)
stellt den ursprünglichen Zustand der Kommandozeile wieder her, nimmt also alle Editorkommandos zurück. (revert-line)
emacs Modus (C-e)
schaltet aus dem vi-Modus in den emacs-Modus. (emacs-editing-mode)
 

Der Kommandozeilenspeicher (history)

      Die bash speichert eine gewisse Anzahl kompletter Kommandozeilen ab und erlaubt dem Benutzer, den Kommandozeilenspeicher auf zwei verschiedene Weisen anzusprechen.

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.

Der Kommandozeilenspeicher im Editor

  Im Gegensatz zu den Vorbildern emacs oder vi ist für den Kommandozeileneditor der Arbeitsbereich auf die aktuelle Zeile beschränkt. Absätze und Seiten existieren hier nicht. Mit dem Kommandozeilenspeicher eröffnet sich aber doch eine zweite Dimension, die das Blättern und Suchen in alten Zeilen zu einer praktischen Erweiterung des Editors macht.
Abschluß einer Kommandozeile (RETURN)
Wie bereits gesagt, wird jede Kommandozeile mit einem Zeilenende (RETURN) abgeschlossen. Dabei ist es egal, wo sich die Einfügemarke innerhalb der Zeile gerade befindet, es wird immer die gesamte Zeile bearbeitet. Wenn sie nicht leer ist, wird sie sofort im ,,rohen`` Zustand in den Kommandozeilenspeicher übernommen.[*] Wenn die Shellvariable history_control das Wort `ignorespace' enthält, werden Kommandozeilen, die mit einem Leerzeichen beginnen, nicht gespeichert. Enthält die Variable das Wort `ignoredups', werden nur die Kommandozeilen gespeichert, die sich von der zuletzt gespeicherten unterscheiden. Mit `ignoreboth' werden die beiden Features eingeschaltet.

Wie alle Funktionen des Editors kann diese Funktion auf beliebige Tasten gelegt werden, wenn auch in diesem Fall davon abzuraten ist. (accept-line)

Kommando zurück (C-p)
blättert im Kommandozeilenspeicher eine Position zurück und gibt die komplette Zeile zum Editieren auf den Bildschirm. Diese Funktion ist auch an die HOCH-Taste des Cursorblocks gebunden. (previous-history)
Kommando vorwärts (C-n)
blättert im Kommandozeilenspeicher eine Position vorwärts und gibt die komplette Zeile zum Editieren auf den Bildschirm. Diese Funktion ist auch über die RUNTER-Taste des Cursorblocks zu erreichen. (next-history)
zum ersten Kommando (M-<)
holt die erste Kommandozeile aus dem Kommandozeilenspeicher in den Editor. (beginning-of-history)
zum letzten Kommando (M->)
holt die letzte Kommandozeile aus dem Kommandozeilenspeicher in den Editor. end-of-history)
Kommando inkrementell rückwärts suchen (C-r)
sucht schrittweise (inkrementell)rückwärts im Kommandozeilenspeicher nach einer Kommandozeile mit exakt passendem Muster. Das gesuchte Muster wird interaktiv eingegeben und die erste passende Zeile sofort angezeigt. Reguläre Ausdrücke im Muster werden nicht interpretiert, sondern buchstäblich mit den gespeicherten Kommandozeilen verglichen. Das Suchmuster kann mit BACKSPACE schrittweise zurückgenommen werden; das erste andere Editorkommando während der interaktiven Eingabe des Suchmusters beendet die Suche. (reverse-search-history)
Kommando rückwärts suchen (C-p)
sucht nach der vollständigen Eingabe einer Zeichenkette die erste darauf passende Kommandozeile in der History. (non-incremental-reverse-search-history)
Kommando inkrementell vorwärts suchen (C-s)
sucht mit jedem weiteren eingegebenen Buchstaben schrittweise (inkrementell) vorwärts im Kommandozeilenspeicher von der aktuellen Zeile an nach einer Kommandozeile mit einem bestimmtem Muster. Die Bearbeitung des Musters erfolgt in der gleichen Weise wie beim reverse-search-history-Editorkommando. (forward-search-history)
Kommando vorwärts suchen (M-n)
sucht nach der Eingabe einer Zeichenkette vorwärts in der History nach der ersten passenden Kommandozeile. (non-incremental-forward-search-history)
Kommandozeile erweitern (M-C-e)
führt die weiter unten beschriebene History-Expansion im C-Shell-Stil und die Synonymerweiterung aus, ohne die Kommandozeile auszuführen. Die Zeile kann daraufhin weiter bearbeitet werden. (expand-line)
letztes Argument einfügen (M-., M-_)
fügt das letzte Argument des letzten Kommandos an der Einfügemarke ein. (insert-last-argument)
n-tes Argument einfügen (M-C-y)
fügt das n-te Argument der letzten Kommandozeile beim Cursor ein. Die Zahl wird als Argument (siehe oben) dem Kommando vorangestellt, Defaultwert ist 1. (yank-nth-arg)
ausführen und nächstes Kommando (C-o)
führt das mit den Cursortasten in die Kommandozeile zurückgeholte Kommando aus und gibt nach dessen Beendigung automatisch die auf die ausgeführte Zeile folgende Zeile aus der History aus. (operate-and-get-next)

History im C-Shell-Stil

Zusätzlich zu den oben beschriebenen Tastenfunktionen des Editors kann der Kommandozeilenspeicher mit einem History-Mechanismus benutzt werden, dessen Verwendung der C-Shell nachempfunden ist.[*] Diese History-Expansion kann mit dem Shellkommando set +H ausgeschaltet werden.

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.

Bezugnahme auf eine frühere Kommandozeile

  Zum Auswählen einer Kommandozeile im Kommandozeilenspeicher gibt es verschiedene Möglichkeiten. Prinzipiell leitet ein Ausrufezeichen `!' die History-Substitution ein. Nur wenn das Ausrufezeichen nach einem Fluchtsymbol `\' steht oder von einem SPACE, RETURN, TAB, `=' oder `(' gefolgt wird, findet die Substitution nicht statt.

Anstelle des Ausrufezeichens kann in der Shellvariablen histchars auch ein anderes Zeichen mit dieser Funktion belegt werden.

!!
wählt die letzte Zeile im Kommandozeilenspeicher.
!n
wählt die Zeile Nummer n.
!-n
wählt die aktuelle Zeile minus n
!Zeichenkette
wählt die letzte Kommandozeile, deren Anfang mit der Zeichenkette übereinstimmt.
!?Zeichenkette[?]
wählt die letzte Kommandozeile, in der die Zeichenkette an irgendeiner Position vorkommt.
^Alt^Neu
ist eine Abkürzung für !!:s^Alt^Neu^ zur Ersetzung der Zeichenkette Alt durch Neu in der letzten Kommandozeile. Diese Konstruktion muß allein auf der Kommandozeile stehen.
!#
steht für die aktuelle Kommandozeile bis hier hin.

Bezugnahme auf ein Wort einer früheren Kommandozeile

Auf die Kommandozeilenreferenz kann eine Wortreferenz folgen. Diese Wortreferenz wird durch einen Doppelpunkt `:' von der Zeilenreferenz getrennt. Wenn die Wortreferenz mit einem `^', `$', `*' oder `%' beginnt, kann der Doppelpunkt auch weggelassen werden. Die Wörter einer Kommandozeile sind vom Zeilenanfang an mit Null beginnend numeriert.

n
bezeichnet das nte Wort. Das Wort 0 ist in der Regel der Kommandoname.
^
(Caret) steht für das erste Argument (das ist Wort Nummer 1).
$
bezeichnet das letzte Argument.
%
steht für das bei ?Zeichenkette? gefundene Wort.
n-m
ist der Bereich vom nten bis zum mten Wort
*
steht für alle Argumente, also die Wörter 1-$. Wenn das Kommando nur aus einem Wort besteht, wird die leere Zeichenkette zurückgeliefert.

Modifikation der bezogenen Kommandozeilen

Nach (oder anstelle) der Wortreferenz können noch ein oder mehrere Zeichen zur Modifikation des bezogenen Wortes folgen. Diese Zeichen werden wieder durch Doppelpunkte getrennt.
h
schneidet alle Zeichen nach dem letzten Slash von dem referenzierten Bereich der Kommandozeile ab. Die Funktion ist in gewisser Weise mit dem Shellutility dirname vergleichbar.  
r
schneidet eine Endung der Form `.xxx' nach dem letzten Punkt ab.
e
läßt nur die Endung in der oben beschriebenen Form übrig.
t
entfernt aus dem referenzierten Bereich der Kommandozeile alles bis zum letzten Slash. Die Funktion ist dem Shellutility basename vergleichbar.  
p
zeigt die entstandene Kommandozeile sofort an, ohne sie auszuführen.
[g]s/Alt/Neu [/]
ersetzt die Zeichenkette Alt bei ihrem ersten Auftreten durch Neu. Durch den Zusatz g kann erreicht werden, daß alle Vorkommen von Alt ersetzt werden. Anstelle der Slashes können beliebige andere Zeichen benutzt werden.

Beispiele für die History-Funktion

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.  

Anpassung des Kommandozeileneditors

  Der Kommandozeileneditor der bash benutzt die GNU-readline  Bibliotheksfunktionen. Wie bereits gesagt, bietet readline zwei Standardbelegungen an, zwischen denen Sie mit dem set-Shellkommando hin und her schalten können.

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

Wenn Sie z. B. anstelle des aufwendigen set-Kommandos die Tastenkombination CONTROL-x v zum Umschalten in den vi-Modus und die Kombination CONTROL-x e zum Zurückschalten in den EMACS-Modus verwenden wollen, erreichen Sie das mit den folgenden Kommandos:
$ 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.

bell-style
(audible) regelt das Verhalten von readline, wenn dem Benutzer ein Signal gegeben werden soll. Außer audible sind none und visible möglich.
comment-begin
(`#') In dieser Variablen kann das Zeichen bestimmt werden, das durch das vi-comment-Kommando in die erste Spalte der Kommandozeile geschrieben wird. Durch das Nummernzeichen (Voreinstellung) wird die Ausführung der Zeile unterdrückt.
completion-query-items
(100) In dieser Variablen kann eine Anzahl bestimmt werden, bis zu der mögliche Erweiterungen ohne Nachfrage angezeigt werden. 
convert-meta
(On) Bleibt dieser Schalter gesetzt, werden Zeichen mit gesetztem achten Bit zu einer ESC-Sequenz mit dem entsprechenden ASCII-Zeichen verarbeitet.
disable-completion
(Off) Das Setzen dieses Schalters unterdrückt die Kommandozeilenerweiterung.
editing-mode
(emacs) Durch Belegen dieser Variablen mit ,,vi`` wird die vi-Tastaturbelegung eingeschaltet. Einzige Alternative ist der voreingestellte emacs-Modus.
enable-keypad
(Off) Wenn dieser Schalter auf ``On'' gesetzt wird, versucht readline den Ziffernblock zu aktivieren.
expand-tilde
(Off) Wenn der Schalter eingeschaltet wird, führt readline eine Tildenerweiterung bereits beim Versuch einer Kommandozeilenkomplettierung aus.
horizontal-scroll-mode
(Off) Wird dieser Schalter auf ,,On`` gesetzt, so wird beim Schreiben der Kommandozeile über den rechten Bildschirmrand hinaus die Zeile nach links verschoben, ansonsten wird sie umgebrochen.
input-meta
(Off) Wenn dieser Schalter ,,On`` gesetzt wird, erlaubt die Shell die Eingabe von 8-Bit-Zeichen (zum Beispiel Umlaute) auf der Kommandozeile.
keymap
(emacs) Diese Variable stellt die Tastaturtabelle für readline ein. Gültige Werte sind emacs, emacs-standard, emacs-meta, emacs-ctlx, vi, vi-standard, vi-command oder vi-insert. vi ist äquivalent zu vi-command und emacs entspricht emacs-standard.
mark-directories
(On) Solange der Schalter auf ``On'' bleibt, wird bei der Kommandozeilenerweiterung ein / an einen Verzeichnisnamen angehängt.
mark-modified-lines
(Off) Wird dieser Schalter ,,On`` gesetzt, werden alle Zeilen in der history mit einem Asterisk `*' gekennzeichnet, die im Editor verändert wurden.
meta-flag
(Off) entspricht dem Schalter input-meta.
output-meta
(Off) Wenn dieser Schalter ,,On`` gesetzt wird, zeigt die bash auf der Kommandozeile 8-Bit-Zeichen an.
show-all-if-ambigous
(Off) Die Veränderung dieses Schalters auf ``On'' veranlaßt readline, bei Komplettierungsversuchen mit mehreren Möglichkeiten sofort alle Varianten anzuzeigen, anstatt ein Signal zu geben.
visible-stats
(Off) Wenn dieser Schalter auf ``On'' gesetzt wird, erscheinen bei der Liste möglicher Erweiterungen die Symbole für die Dateitypen, wie sie auch von ls -F angezeigt werden.

Bedingte Ausführung von .inputrc

Ä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 term=Terminal
testet auf die Übereinstimmung mit der TERM-Umgebungsvariablen.
$if bash
leitet den Teil von .inputrc ein, der speziell für die bash bestimmt ist. Andere Programme, die mit der readline-Library arbeiten, werden mit der selben .inputrc-Datei initialisiert.
$if mode=Modus
ermöglicht die Unterscheidung der verschiedenen Editiermodi: emacs, emacs-meta,emacs-ctlx, vi, vi-move und vi-insert.

Beispiel:

$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.

 

Der erweiterte Editor: sekundärer Prompt

  Viele Operationen der Shell werden mit bestimmten Symbolen eingeleitet und müssen mit weiteren Symbolen abgeschlossen werden. Beispielsweise muß eine for-Schleife durch ein done abgeschlossen werden, eine (-Klammer durch eine ), eine mit Anführungszeichen begonnene Zeichenkette muß mit Anführungszeichen abgeschlossen werden und so weiter.

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.

Wenn die Shelloption cmdhist gesetzt ist, wird ein aus mehreren Zeilen bestehendes Kommando als ein einziger Eintrag im History-Speicher behandelt. Vor bash Version 2.0 wurde dieses Feature durch die Shellvariable command_oriented_history gesteuert.

Interpretation der Kommandozeile

  Mit dem accept-line-Kommando (RETURN) im Editor ist der im eigentlichen Sinn interaktive Teil der Shellbenutzung zu Ende. Die folgende Interpretation der Zeile durch die Shell führt normalerweise zur Erzeugung eines neuen Prozesses, in dem das eben aufgerufene Programm abläuft. Bevor das geschieht, werden aber von der Shell selbst noch eine ganze Reihe von Veränderungen an der Zeile durchgeführt. Diese Interpretation findet bei der interaktiven Shell auf exakt die gleiche Weise statt wie im Shellprogramm.

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.

Kommentare

   In Shellscripten können an beliebigen Stellen Kommentare durch ein Nummern- oder Hash-Zeichen `#' eingeleitet werden. Der gesamte Zeilenrest wird bei der Interpretation von der Shell ignoriert.

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

Der Status

   

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.

Shell Grammatik

 

Reservierte Wörter

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 { }

Atome, Wörter, Token

 

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.

Kommandos - nicht unbedingt einfach

In einem Multitasking-Betriebssystem macht es durchaus Sinn, mehr als ein Kommando in einer Zeile aufzurufen. So ein zusammengesetztes Kommando besteht aus mehreren einfachen Kommandos. Zur Trennung von einfachen Kommandos werden Kontrolloperatoren verwendet, die aus den oben genannten Sonderzeichen zusammengesetzt sind:

| & || && ; ;; ( )

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.

Quotierung

     Quotierung wird benutzt, um die spezielle Bedeutung von Kontrollzeichen, reservierten Wörtern oder Namen auszuschalten. Auf diese Weise können Parameter an Funktionen übergeben werden, die Sonderzeichen, Namen oder reservierte Wörter enthalten, ohne daß die Shell eine Veränderung an den Parametern vornimmt.

Es gibt drei Formen der Quotierung:

1.
durch das Fluchtsymbol \  (Backslash) 
2.
durch Hochkomma ' (Quote)  
3.
durch Anführungszeichen " (Doublequote)  

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.

Ein-/Ausgabe-Umleitung

   Jedes Programm erhält automatisch beim Start drei offene ,,Datenkanäle``: die Standardeingabe, die Standardausgabe und die Standardfehlerausgabe.

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.

Eingabeumleitung

 

[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.

Ausgabeumleitung

 

[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.

Anfügen der Ausgabe an eine existierende Datei

[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.

Zusammenfassung der Standardausgabe mit der Standardfehlerausgabe

 

&>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.

Shellscript-Dokumente

    <<[-]Wort
Dokument
Begrenzer

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.

Verdoppelung der Dateikennung

[n]<&Wort
kopiert die in Wort enthaltene (ganzzahlige) Eingabedateikennung. Es wird die neue Dateikennung n als Eingabekanal erzeugt oder eine existierende Kennung überschrieben.

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!

Öffnen einer Datei zum Lesen und Schreiben

[n]<>Wort
öffnet die im Wort benannte Datei zum Lesen und Schreiben.

Pipelines

     

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.

Hintergrundprozesse

      

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.

 

Listen

 

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.

Listen mit ; und &

 

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.

Bedingte Ausführung

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.[*]

 

Gruppen und Kontrollstrukturen: Blöcke, Schleifen, Verzweigungen, Funktionen

 

Einzelne Kommandos oder Listen können auf verschiedene Weisen weiter zu Gruppen zusammengefaßt werden:

{Liste;}
Mit den geschweiften Klammern werden die Kommandos der Liste zu einer einfachen Gruppe zusammengefaßt. Diese Klammerung entspricht der in mathematischen Ausdrücken und dient der Assoziierung nieder- oder gleichrangig verknüpfter Kommandos.

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.

(Liste)
Durch runde Klammerung werden die Kommandos einer Liste in einer eigenen (Shell-) Umgebung ausgeführt. Wenn von den Kommandos der Liste Veränderungen an der Shellumgebung vorgenommen werden, sind diese außerhalb der eingeklammerten Gruppe nicht sichtbar. Wenn zum Beispiel innerhalb einer so geklammerten Gruppe das Verzeichnis gewechselt wird, beziehen sich alle weiteren Kommandos innerhalb der Gruppe auf dieses Verzeichnis; außerhalb der Klammerung bleibt das ,,alte`` Verzeichnis aktuell. Beispiel:

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.

for Name [in Wort] do Liste done
  Mit dieser Konstruktion stellt die bash die von vielen Programmiersprachen bekannte und bewährte for-Schleife bereit. Mit Name wird eine Shellvariable definiert, die in jedem Schleifendurchlauf einen neuen Wert erhält. Die Anzahl der Schleifendurchläufe entspricht der Anzahl der vorhandenen Werte.

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.

while Liste do Liste done
  Von anderen Programmiersprachen ebenso bekannt ist die while ... do ... done-Schleife. Hier wird der Schleifenkörper `do Liste done' so lange wiederholt, bis die in `while Liste' formulierte Bedingung falsch ist. Das ist der Fall, wenn das letzte Kommando der while Liste einen Status ungleich Null liefert.

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.

until Liste do Liste done
  Die until-Schleife entspricht der while-Schleife mit dem Unterschied, daß der do-Teil so lange ausgeführt wird, wie das letzte Kommando der `until Liste' einen Status ungleich Null liefert.

if Liste then Liste [elif  Liste then Liste ...] [else Liste] fi
Mit der if-Konstruktion werden die Kommandos der then Liste unter der Bedingung ausgeführt, daß das letzte Kommando der if Liste ,,wahr`` ist, also einen Status Null liefert.

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
fi
Ein 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.

case Wort in [Muster  [ |Muster ...] ) Liste ;; ...] esac
Mit der case-Anweisung können leicht Verzweigungen programmiert werden, bei denen viele Fälle unterschieden werden.

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.

select Name [in Wort...;] do Liste done
Die select- Kontrollstruktur bietet eine Kombination aus menügesteuerter Verzweigung und Schleife.       

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.

[function] Name () {Liste}
    definiert eine neue Scriptfunktion Name. 

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.

 

Parameter

  

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.

Shell- und Umgebungsvariable

    Shellvariable haben auch in der interaktiven Shell eine große Bedeutung.

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.

BASH_ENV
entspricht in der Funktion der Shellvariablen ENV. Im gegensatz zu letzterer wird BASH_ENV jedoch nur verwendet, wenn die Shell zur Bearbeitung eines Shellscripts unter den Namen bash aufgerufen wird. 
CDPATH
ist eine durch Doppelpunkt getrennte Liste von Verzeichnissen. Wenn beim cd-Shellkommando kein absoluter Verzeichnisname und kein Verzeichnis relativ zum aktuellen Verzeichnis benannt wird, werden alle Verzeichnisse im CDPATH nach einem passenden Verzeichnis durchsucht. In das erste passende Verzeichnis wird gewechselt. 

ENV
enthält den Namen einer Datei, die Kommandos zur Initialisierung für die Shellumgebung beim Bearbeiten von Shellscripts enthält. (z.B. die Datei ~/.bashrc) 
FCEDIT
benennt einen anderen Editor als vi als Standardeditor für das fc-Shellkommando.
FIGNORE
kann eine durch Doppelpunkte getrennte Liste von Dateiendungen enthalten, die bei der automatischen Dateinamenerweiterung ignoriert werden sollen. Beispielsweise kann diese Variable mit ,,.o:.bak:.old:~`` belegt werden.
GLOGBIGNORE
kann eine durch Doppelpunkte getrennte Liste von Namen und Mustern enthalten, die bei der Pfadnamenerweiterung ignoriert werden sollen.  
histchars
enthält zwei oder drei Zeichen zur Kontrolle der Wiederholung von Kommandos aus dem Kommandozeilenspeicher. Das erste Zeichen leitet eine Kommandozeilenerweiterung aus dem Kommandozeilenspeicher ein. Die Voreinstellung ist `!'. Das zweite Zeichen leitet die ``Schnellsubstituion'' ein und ist mit ^ 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.
HISTCONTROL oder history_control
bestimmt, welche Kommandos in den Kommandozeilenspeicher geschrieben werden. Wenn die Variable das Wort `ignorespace' enthält, werden nur die Zeilen in den Speicher geschrieben, die nicht mit einem Leerzeichen beginnen. Wenn die Variable das Wort `ignoredups' enthält, werden alle Zeilen, die der zuletzt gespeicherten Zeile entsprechen, nicht gespeichert. `ignoreboth' ist die Kombination der beiden anderen Schalter. Wenn die Variable nicht gesetzt ist oder irgendeinen anderen Wert enthält, werden alle Kommandozeilen in den Kommandozeilenspeicher geschrieben.
HISTFILE
benennt eine Datei, in die der Inhalt des Kommandozeilenspeichers beim Beenden der Shell automatisch gesichert wird. Der Kommandozeilenspeicher wird beim Start einer neuen Shell aus dieser Datei aufgefüllt. Voreinstellung für HISTFILE ist ~/.bash_history Wenn Sie (z.B. im X Window System) mehrere Shells gleichzeitig mit derselben Sicherungsdatei benutzen, bleiben nur die Kommandozeilen der zuletzt beendeten Shell erhalten.
HISTFILESIZE
bestimmt die Anzahl der im HISTFILE zwischen zwei Sitzungen gespeicherten Kommandozeilen. Alle älteren Zeilen gehen verloren.
HISTIGNORE
kann eine durch Doppelpunkt getrennte Liste von Mustern enthalten, die auf Kommandozeilen angewendet werden, nachdem diese die Prüfung von HISTCONTROL bestanden haben. Es werden nur solche Kommandozeilen in die History übernommen, auf die das Muster nicht zutrifft. Zusätzlich zu den bei der Pfadnamenerweiterung üblichen Jokerzeichen bedeutet bei HISTIGNORE das Zeichen & die vorangehende Zeile in der History.
HISTSIZE
setzt die Anzahl der im Kommandozeilenspeicher erinnerten Zeilen fest. Alle älteren Zeilen werden vergessen.
HOME
ist das Heimatverzeichnis des aktuellen Benutzers. Dieses Verzeichnis wird in der Datei /etc/passwd bestimmt und von login automatisch in die Variable HOME geschrieben. Das in HOME gespeicherte Verzeichnis ist der Standardwert für das cd-Shellkommando.   
HOSTFILE oder hostname_completion_file
ist der Name einer Datei mit dem gleichen Format wie die Datei /etc/hosts. Die Einträge dieser Datei werden zur Hostnamenerweiterung verwendet.
IFS
ist der ,,interne Feldseparator``. Alle Zeichen dieser Shellvariablen werden als Trenner von Wörtern erkannt. Die Standardbelegung für IFS ist Leerzeichen, Tabulator und Zeilenende. 
IGNOREEOF
hat nur eine Bedeutung, wenn die Shell interaktiv läuft. Wenn die Variable eine ganze Zahl enthält, so wird diese Anzahl von `EOF'-Zeichen   (CTRL-D) für das Dateiende bzw. das Ende der Eingabe abgewartet, bevor die Shell verlassen wird. Zu jedem `EOF' wird der Hinweis ausgegeben, daß die Shell mit logout verlassen werden soll.

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.

INPUTRC
enthält den Namen der Initialisierungsdatei für readline.
LANG
dient zur ``weichen'' Voreinstellung für alle Locale-Kategorien. Jede Einzelkategorie kann wirksam mit einem anderen Wert belegt werden.
LC_ALL
dient zur verbindlichen Einstellung aller Locale-Kategorien. Abweichende Einstellungen einzelner Kategorien werden von dem hier festgelegten Wert verdrängt.
LC_COLLATE
Diese Variable wird von der bash ausgewertet, um die Sortierfolge der Dateinamen bei der Pfadnamen-Expansion festzuleten.
LC_MESSAGES
Diese Variable wird von der bash ausgewertet, um das Locale für die Übersetzung der $ Zeichenketten zu bestimmen.
MAIL
enthält den Namen der Datei, in der die elektronische Post für den Benutzer gespeichert wird. Wenn diese Datei nicht leer ist, wird der Anwender darauf hingewiesen, daß Post für ihn da ist.
MAILCHECK
spezifiziert die Zeitintervalle, nach denen die Shell prüft, ob Post da ist. Die Voreinstellung ist 60 Sekunden.
MAILPATH
ist eine durch Doppelpunkt getrennte Liste von (absoluten) Dateinamen, in denen Post für den Benutzer ankommen kann. Zu jeder Datei kann eine durch `?' eingeleitete Zeichenkette angegeben werden, die auf dem Bildschirm ausgegeben wird, wenn in der entsprechenden Datei Post angekommen ist.
MAIL_WARNING
ist ein Schalter. Ist die Variable gesetzt (egal, welcher Wert), erfolgt eine Warnung, wenn auf die Postdatei zugegriffen wurde. Damit kann sowohl festgestellt werden, ob neue Mail angekommen ist, als auch jeder (möglicherweise illegale) Lesezugriff auf die Mailbox überwacht werden.

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.

OPTERR
ist ein Schalter. Wenn die Variable den Wert 1 enthält, werden die Fehlermeldungen der getopts-Shellfunktion ausgegeben. Enthält sie eine 0, werden die Fehlermeldungen unterdrückt.
PATH
enthält eine durch Doppelpunkt getrennte Liste von Verzeichnissen. Wenn ein einfaches Kommando nicht als internes Shellkommando erkannt wird und nicht mit komplettem Pfadnamen (das ist der Pfad vom aktuellen Verzeichnis oder vom Wurzelverzeichnis aus) angegeben wird, dann sucht die Shell in allen Verzeichnissen der PATH-Variablen nach einem Programm mit passendem Namen und führt es aus.

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.

PROMPT_COMMAND
benennt ein Kommando, das vor jeder Eingabeaufforderung automatisch ausgeführt wird.
PS1
ist die (rohe) Zeichenkette, die als Eingabeaufforderung   (Prompt) die Arbeitsbereitschaft der Shell anzeigt. Die Variable kann eine   Reihe symbolischer Namen enthalten, die vor der Ausgabe nach den im Abschnitt ``Eingabeaufforderung'' erläuterten Regeln erweitert werden. Die Voreinstellung ist `\$'.
PS2
enthält die Zeichenkette für die sekundäre Eingabeaufforderung. Sie wird genau wie PS1 erweitert. Die sekundäre Eingabeaufforderung erscheint, wenn zu einem gegebenen Kommando interaktiv über die Shell weitere Kommandos oder Parameter von der Tastatur gelesen werden sollen. (Zum Beispiel in einer for-Schleife) Die Voreinstellung ist `> '.
PS3
enthält den Prompt, mit dem die Eingabe bei der select-Konstruktion angefordert wird (siehe select). Voreinstellung ist `#?'.
PS4
wird zur Anzeige der erweiterten Kommandos mit der Option `-x' benutzt (siehe set). Voreinstellung ist `+'.
TIMEFORMAT
In dieser Shellvariablen kann ein Formatstring abgelegt werden, der die Ausgabe der shellinternen Funktion time bestimmt. Ähnlich wie bei printf leitet das Prozentzeichen % die Platzhalter für Zeitinformation im String ein.
%[p][l]R
(real time) die tatsächlich während der Ausführung des Kommandos vergangene Zeit
%[p][l]U
(user time) die für die Ausführung des Kommandos im User-Modus verbrauchte Zeit
%[p][l]S
(system time) die für die Ausführung des Kommandos im Kernel-Modus verbrauchte Zeit
%P
die Auslastung der CPU durch das Kommando in Prozent
Das optionale Argument p gibt die Anzahl der Dezimalstellen an, mit denen die Sekundenangaben formatiert werden. Die maximale Genauigkeit und gleichzeitig die Voreinstellung beträgt drei Dezimalstellen.

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.

TMOUT
Mit dieser Variablen kann die Shell veranlaßt werden, nach einer bestimmten Zeit ohne Benutzeraktivität, also ohne Eingabe, automatisch zu beenden. Nur wenn die Variable eine Zahl enthält, wird diese Anzahl Sekunden auf die Eingabe gewartet.

Die folgenden Variablen werden automatisch durch die Shell gesetzt. Die meisten können vom Benutzer nicht verändert direkt werden.  

BASH
beinhaltet den kompletten Pfadnamen der aktuellen Shell.
BASH_VERSINFO
ist eine Array-Variable mit den einzelnen Komponenten der bereits in BASH_VERSION zusammengefaßten Versionsnummer.
BASH_VERSION
beinhaltet die Versionsnummer der Shell.
DIRSTACK
ist eine Array-Variable, die den aktuellen Verzeichnisstapel enthält. Die Reihenfolge der Einträge entspricht der von dirs angezeigten. Es ist möglich, einzelne Einträge zu verändern. Um einen neuen Eintrag zu erzeugen oder einen existierenden zu entfernen sind die Shellkommandos pushd und popd zu verwenden. Sollte DIRSTACK durch unset gelöscht werden gehen die besonderen Eigenschaften verloren, auch wenn das Array anschließend wieder erzeugt wird.
EUID
ist die effektive Benutzerkennung des Anwenders. Während der Ausführung von Programmen, bei denen das SUID-Bit gesetzt ist, wird die effektive Benutzerkennung des Eigentümers der Programmdatei gesetzt.
GROUPS
ist eine Array-Variable mit den numerischen IDs sämtlicher Gruppen, denen der User angehört.
HISTCMD
enthält die Nummer des aktuellen Kommandos so, wie sie in der History gespeichert wird.
HOSTTYPE
enthält den Hostnamen des lokalen Rechners.
HOSTTYPE
enthält eine Kennung zur Identifikation des Rechnertyps. Für Linux kommen nur die Typen `i386' und `i486' in Frage.
LINENO
enthält die aktuelle Zeilennummer im Shellscript.  Wenn die Variable innerhalb einer Scriptfunktion aufgerufen wird, entspricht die Zahl den bis zum Aufruf innerhalb der Funktion ausgeführten einfachen Kommandos. Außerhalb von Shellscripten ist diese Variable nicht sinnvoll belegt. Wenn die LINENO-Shellvariable mit dem unset-Kommando gelöscht wird, kann sie nicht wieder mit ihrer automatischen Funktion erzeugt werden.
MACHTYPE
enthält die Typenbezeichnung des Betriebssystems für das die Shell erzeugt wurde. Für Intel-Linux ist das etwas wie i586-pc-linux-gnu
OLDPWD
ist das zuletzt aktuelle Verzeichnis (wird ebenfalls vom cd-Shellkommando gesetzt).
OPTARG
enthält das Argument zu der zuletzt von getopts ausgewerteten Option (siehe getopts).
OPTIND
enthält den Index der zuletzt von getopts ausgewerteten Option (siehe getopts).
OSTYPE
enthält den Namen des Betriebssystems, also in diesem Fall `Linux'.
PIPESTATUS
ist eine Array-Variable mit den Status-Rückgabewerten aller Kommandos einer Pipeline.
PPID
ist die Prozeßnummer des Elternprozesses der Shell.
PWD
ist das aktuelle Verzeichnis, wie es vom cd- Shellkommando gesetzt wird.
RANDOM
liefert bei jeder Abfrage einen neuen Pseudozufallswert. Die Folge von Pseudozufallszahlen kann durch eine Zuweisung an RANDOM initialisiert werden. Gleiche Initialwerte führen zu gleichen Zahlenfolgen.
REPLY
wird vom Shellkommando read gesetzt, wenn keine andere Variable als Rückgabeparameter benannt ist (siehe read).
SECONDS
liefert die Anzahl von Sekunden seit dem Start der aktuellen Shell. Wenn SECONDS ein Wert zugewiesen wird, erhöht sich dieser Wert jede Sekunde automatisch um eins.
SHELLOPTS
enthält eine durch Doppelpunkt getrennte Liste aller aktiven Shelloptionen. Diese Variable kann bei der laufenden Shell nur gelesen werden. Die einzelnen Einträge lassen sich mit dem Shellkommando set -o verändern. Wird die Shellvariable in die Umgebung einer neu gestarteten Shell exportiert, übernimmt die neue Shell die Einträge vor dem Lesen anderer Initialisierungsdateien.
SHLVL
steht für den Shell-Level. Bei jedem Aufruf einer neuen Shell in der Shell wird der Shell-Level um eins erhöht. Eine Möglichkeit, zwischen den Levels zu wechseln, besteht nicht.  
UID
ist die Benutzerkennung des aktuellen Anwenders. Diese Kennung ist in der Datei /etc/passwd dem Benutzernamen zugeordnet.

Eindimensionale Arrays

  

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
$

 

Positionsparameter

   Ein Positionsparameter wird durch eine positive ganze Zahl bezeichnet, also durch Ausdrücke wie $1, $2 ...referenziert. Die Positionsparameter werden beim Aufruf der Shell in der Kommandozeile oder   durch das set-Shellkommando (mit den Optionen `-' oder `-' , siehe set) gesetzt.

Wenn ein Positionsparameter mit mehr als einer Stelle (>9) bezeichnet werden soll, muß er in geschweifte Klammern gesetzt werden: z.B. ${12}.

Spezialparameter

    Einige Parameter haben eine besondere Bedeutung. Diese Parameter können nur gelesen werden. Eine Zuweisung an diese Parameter ist verboten.
*
steht (als Parameter) für alle Positionsparameter von 1 an. In Anführungszeichen gesetzt, steht ``$*`` für ein einziges Wort, bestehend aus dem Inhalt aller Positionsparameter mit dem ersten IFS als Trennzeichen.
@
steht ebenfalls für alle Positionsparameter von 1 an. In Anführungszeichen gesetzt, wird es aber durch die Werte der einzelnen Positionsparameter (jeweils ein einzelnes Wort) ersetzt.
#
steht für die Anzahl der Positionsparameter.
?
liefert den Rückgabewert (Status) des zuletzt ausgeführten Kommandos.
-
steht für die Optionsflags (von set oder aus der Kommandozeile).
$
steht für die Prozeßnummer der Shell.
!
steht für die Prozeßnummer des zuletzt im Hintergrund aufgerufenen Kommandos.
0
steht für den Namen des Shellscripts oder der Shell selbst, wenn kein Shellscript ausgeführt wird.
_
(Unterstrich) steht für das letzte Argument des zuletzt ausgeführten Kommandos (nach allen Erweiterungen).

Erweiterung

 Nachdem die Kommandozeile in einzelne Kommandos zerlegt ist, werden die Wörter jedes einzelnen Kommandos nach Token durchsucht, die zu ersetzen sind. Es gibt acht Formen der Erweiterung:
1.
Klammererweiterung { , }
2.
Tildenerweiterung ~
3.
Parameter- und Variablenerweiterung ${  }
4.
Kommandosubstitution `   ` oder $(  )
5.
Arithmetische Erweiterung $((  )) (vor Version 2.0 $[  ])
6.
Prozeßsubstitution <(  )
7.
Worttrennung
8.
Pfadnamenerweiterung * ? [  ]

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.

Klammererweiterung

    Die Klammererweiterung generiert aus einer in geschweiften Klammern eingeschlossenen Liste von Bausteinen mehrere Zeichenketten (Wörter). Wenn die Klammer von konstanten Zeichenketten eingeschlossen ist, werden diese Zeichenketten an jedes der erzeugten Wörter angefügt. Es können mehrere Klammern verschachtelt werden.

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.

Tildenerweiterung

   Wenn ein   Wort mit einer Tilde (`~