Für viele Einsteiger ist die Shell ein Mysterium, das fortgeschrittenen Anwendern und Linux-Gurus vorbehalten bleibt. Dabei verbirgt sich hinter dem Prompt ein flexibles Programm, mit dem Anwender beinahe jede Aufgabe lösen können.
Die Geschichte der Unix-Shells begann Ende der sechziger Jahre. Zu dieser Zeit entwickelten Ken Thompson und Dennis Ritchie das Betriebssystem Unix. Allerdings fehlte den beiden Entwicklern eine Benutzerschnittstelle zwischen System und Anwender.
Diese Schnittstelle sollte Informationen zwischen dem Betriebssystem und dem Benutzer vermitteln. Auf der Tastatur eingegebenen Befehle sollten ebenso vom Rechner verstanden werden wie die Mitteilungen der Maschine vom Menschen. Darum nennt man die Shell auch einen Kommandointerpreter.
In diese Lücke trat Stephen R. Bourne mit seiner Arbeit. Die Bourne-Shell (auch AT&T-Shell oder schlicht sh genannt) ist mittlerweile die klassische Unix-Shell. Sie ermöglichte die Arbeit mit Skripten, war jedoch in der interaktiven Funktionalität etwas unhandlich. So war eine History-Funktion, um bereits eingegebene Kommandos einzusehen und zu bearbeiten, weder implementiert noch vorgesehen. Nach und nach folgten weitere Entwicklungen wie die Korn-Shell (ksh) und die C-Shell (csh).
Als Richard Stallman Anfang der achtziger Jahre das GNU-Projekt in Angriff nahm, stand er vor einer ähnlichen Schwierigkeit wie seinerzeit Thompson und Ritchie: Er benötigte eine Schnittstelle.
Also schrieb er kurzweg seinen eigenen Befehlsinterpreter und nannte ihn Bash. Dieser Name ist Akronym und Wortspiel zugleich und bedeutet Bourne Again Shell. Die Bash basiert mit ihrem Befehlsaufbau zwar auf der Bourne-Shell, vereinigt aber auch Elemente von Korn- und C-Shell in sich.
Neben der Verarbeitung von Befehlen unterstützt die Bash den Anwender durch den Aufruf von anderen Programmen. Mit ihrer ausgefeilten Programmiersprache versetzt sie den User außerdem in die Lage, komplexe Arbeitsabläufe durch Skripte zu automatisieren.
Wenn Sie eine gängige Distribution verwenden, schwimmen Sie geradezu in einem Pool von Shell-Skripten, die unbemerkt im Hintergrund werkeln. Diese Dateien erkennen Sie an den Zeichenfolgen #!/bin/bash oder #!/bin/sh in der ersten Zeile. Der Ausdruck nennt den Pfad zum Kommandointerpreter und wird in Programmiererkreisen Shebang (zusammengesetzt aus Sharp, “#” und Bang, “!”) genannt.
Tasten und Modi
Befehle, die Sie in die Kommandozeile tippen, lassen sich bequem verändern, bevor Sie sie durch die Return-Taste ausführen. Zwei Arten der Texteditierung stehen Ihnen zur Verfügung: Der Vi- und der Emacs-Modus. Diese beiden Standard-Editoren unter Unix verwenden eine Reihe von Tastenkürzeln zum Löschen, Eingeben oder Suchen, die Ihnen auch die Bash zur Verfügung stellt.
Je nachdem, welchen Editor Sie lieber verwenden, schalten Sie die GNU-Shell um: Der Befehl set -o vi wechselt in den Vi-Modus, mit set -o emacs gelangen Sie zurück in den voreingestellten Emacs-Modus.
In Abbildung 1 können Sie den Wechsel beobachten. Das Kommando bind -vgrep keymap zeigt Ihnen, in welchem Modus Sie sich befinden. Der Einfachheit halber beschränken wir uns in diesem Artikel auf den Emacs-Modus.
Schauen wir uns einige Beispiele der Tastenkürzel an. Der Druck auf [Alt-t] vertauscht zwei Wörter vor der Cursor-Position. Mit den Rauf-/Runter-Pfeiltasten wandern Sie durch zuletzt eingegebene Kommandos. Die [Tab]-Taste schließlich expandiert Befehl- oder Dateinamen, und [Strg-r] sucht nach früheren Eingaben. Tabelle 1 zeigt die wichtigsten Tastaturbelegungen in der Übersicht.
Tabelle 1: Emacs-Tastaturbelegung der Bash
| [Strg-r] | Suche nach Kommandos |
| [Strg-l] | Bildschirm löschen |
| [Tab] | Komplettieren von Befehlen und Dateien |
| [Strg-e] | Cursor ans Zeilenende |
| [Strg-a] | Cursor zum Zeilenanfang |
| [Strg-u] | Eingabe löschen |
| [Strg-k] | Eingabe ab Cursor löschen |
| [Strg-d] | Zeichen unter dem Cursor löschen |
| [Alt-t] | Wörter vor dem Cursor vertauschen |
| [Alt-b] | Cursor ein Wort zurück |
| [Alt-f] | Cursor ein Wort vor |
Die Einstellungen zur Tastaturbelegung liegen global in der Datei /etc/inputrc oder für den einzelnen User in ~/.inputrc. Um es gleich vorneweg zu sagen: Die genannten Konfigurationsdateien speichern nicht ausschließlich die Einstellungen der Bash. Durch sie wird eine Funktion namens Readline gesteuert, auf die auch andere Programme (z. B. GNU-Plot, der GNU Debugger gdb oder auch Sax2 und Smbclient) zugreifen. Lassen Sie uns einen Blick in die Datei /etc/inputrc werfen, um ihren Aufbau zu studieren. Sie werden dort Einträge der folgenden Form finden:
# /etc/inputrc Beispieldatei set meta-flag on set output-meta on set convert-meta off "\e[A": previous-history "\e[4~": end-of-line
Die ersten drei mit set beginnenden Zeilen setzen Readline-Variablen. Der Eintrag set meta-flag on erlaubt Ihnen die Eingabe von 8-Bit-Zeichen (also beispielsweise deutsche Sonderzeichen). Die Anweisung set output-meta on gestattet der Shell die Ausgabe eben dieser Zeichen. Die letzte Variable convert-meta off verhindert eine unerwünschte Zeichenkonvertierung. Wie Sie sicher schon erraten haben, eröffnen Ihnen die Variablen die Verwendung von Umlauten in der Kommandozeile.
Die Zeilen darunter sind hingegen nicht so leicht zu entschlüsseln. Die Funktion previous-history blättert rückwärts in der Liste der vormals eingegebenen Kommandos. “\e[A” legt den Parameter auf Pfeil-Oben-Taste, wobei \e das Escape-Zeichen ist. Zum Verständnis dieser Konfiguration hilft Ihnen ein Tool wie showkey, das durch den Druck auf die Pfeil-Oben- und die Zeilenende-Taste folgendes anzeigt:
[andreas]~ > showkey -a
^[[A 27 0033 0x1b
91 0133 0x5b
65 0101 0x41
^[[4~ 27 0033 0x1b
91 0133 0x5b
52 0064 0x34
126 0176 0x7e
Die Ausgabe ^[[4~ entspricht der Definition “\e[4~” in der Datei /etc/inputrc. Sie beschreibt mit der Funktion end-of-line die Cursor-Bewegung ans Zeilenende. ^[[4~ beziehungsweise “\e[4~” entspricht der Taste [Ende]. Unser Beispiel kann von der Ausgabe in Ihrem konkreten Fall in Einzelheiten abweichen, da auch die Konfiguration des X Servers hier eine Rolle spielt. Als Alternative zu showkey bieten sich die Programme xev und xkeycaps auf der grafischen Oberfläche an.
Doch lassen wir es an dieser Stelle mit der Konfigurationsdatei bewenden und experimentieren mit weiteren Einstellungen: dem Befehl bind. Wenn Sie sich detaillierter mit dem Thema Readline-Library auseinandersetzen möchten, bietet Ihnen das System mit man readline das Manual an.
Gebundenes und Entbundenes
Um während der Arbeit in der Shell die Tastenbelegung anzupassen, liefert Ihnen der Befehl bind ein bequemes Verfahren. Mit der Option -P zeigt Ihnen das Kommando beispielsweise eine Liste der aktuellen Bindungen:
[andreas]~ > bind -P | less abort can be found on "\C-g", "\C-x\C-g", "\e\C-g". accept-line can be found on "\C-j", "\C-m". backward-char can be found on "\C-b", "\e[D". backward-delete-char can be found on "\C-h", "\C-?". […]
In unserem Beispiel wird die Ausgabe des Befehls bind -P durch das Zeichen an den Pager less geleitet, damit Sie darin scrollen und lesen können. Fachchinesen nennen diese Art der Kommandoverbindung eine Pipe.
Im obigem Beispiel sehen Sie, dass die Funktion backward-char ausgelöst wird durch die Tasten [Strg-b] oder Pfeil-Links ausgelöst. Die Angabe \C entspricht der Strg-Taste.
Um selber während des Betriebs Tasten neu zu belegen, verwenden Sie den Befehl bind Taste Funktion. Vielleicht haben Sie bereits bemerkt: Die Tastenkombination [Strg-l] löscht den Bildschirm und stellt die Eingabeaufforderung wieder her. Nun nehmen wir uns vor, die Funktion des Refresh an eine neue Tastenkombination zu binden. Zuerst basteln wir uns wieder eine Pipe. Diesmal mit dem Kommando grep, das die Zeile mit der Zeichenkombination C-l herausfiltert:
[andreas]~ > bind -p | grep "C-l" "\C-l": clear-screen
Zur Tastenkombination [Strg-l] gehört also die Funktion clear-screen. Zwecks Gegenprobe rufen wir die Funktion mit der Bind-Option -q auf. Der Parameter -q steht für Query, und das bedeutet soviel wie Anfrage. Damit finden Sie heraus, welche Tastenkombination an eine Funktion gebunden ist:
[andreas]~ > bind -q clear-screen clear-screen can be invoked via "\C-l".
Jetzt lösen wir die Funktion clear-screen durch den Parameter -u (unbind). Um zu testen, ob die Änderung wirksam ist, greifen wir danach erneut zur Query-Option:
[andreas]~ > bind -u clear-screen [andreas]~ > bind -q clear-screen clear-screen is not bound to any keys.
Im nächsten Schritt verwenden wir die bereits genannte Formel bind Taste Funktion und vergewissern uns, dass nun [Strg-t] den Bildschirm reinigt:
[andreas]~ > bind '"\C-t" clear-screen' [andreas]~ > bind -q clear-screen clear-screen can be invoked via "\C-t".
Auf diese Weise löscht nicht mehr [Strg-l], sondern [Strg-t] die Oberfläche der Bash. Allerdings wurde die Funktion transpose-chars (Vertauschen zweier Buchstaben unter dem Cursor) überschrieben. Achten Sie daher darauf, dass Sie nicht bestehende Bindings überschreiben.
Um weitere Bind-Optionen herauszufinden, können Sie in Tabelle 2 nachsehen oder die umfangreiche Anleitung mit man bashbuiltins aufrufen.
Tabelle 2: Bind-Optionen
| bind -f [Datei] | Liest [Datei] als Konfigurationsdatei ein |
| bind -l | Auflistung aller Funktionen |
| bind -p | Listet Funktionen und Bindings wiederverwertbar auf |
| bind -P | Einfache Auflistung von Funktionen und Bindings |
| bind -q | Erfragt die Tastenkombination zur Funktion |
| bind -r Taste | Entbindet die Tasten von allen Funktionen |
| bind -u Funktion | Hebt die Tastenkombination für diese Funktion auf |
| bind -V | Zeigt die Readline-Variablen an |
Dateien über Dateien
Nachdem Sie die Einstellungen um /etc/inputrc bereits kennen gelernt haben, wollen wir uns mit weiteren Bash-Dateien beschäftigen. Die GNU-Shell besitzt eine ganze Reihe unterschiedlicher Konfigurationsdateien, die zu allem Überfluss unterschiedlich eingesetzt werden. SuSE, Red Hat und andere Distributionen spielen hier oft ihr eigenes Spiel.
Halten wir uns zunächst an das, was uns das Bash-Manual man bash mit seinen beinahe 5100 Zeilen verrät. Wenn Sie die Bash als Login-Shell starten, dann liest das Programm der Reihe nach folgende Konfigurationsdateien ein:
*
/etc/profile
- ~/.bash_profile
- ~/.bash_login
- ~/.profile
Das führt uns zur Frage: Was macht eine Bash zur Login-Shell? Nachdem Sie sich auf der Textkonsole angemeldet haben, befinden Sie sich bereits in einer solchen Shell. Die Bash hat aus den oben angeführten vier Dateien die Befehle gelesen und sie bei Ihrem Login ausgeführt.
Einträge darin haben Sinn, wenn Sie beispielsweise Umgebungsvariablen festlegen möchten. Für diesen Zweck bieten sich die globale Datei /etc/profile oder die lokale ~/.profile an, die allerdings erst gelesen wird, wenn die Shell keine ~/.bash_profile findet. Die Login-Shell vererbt ihre Einstellungen an die ihr nachfolgenden Shells und konserviert damit die festgelegte Umgebung.
Etwas undurchsichtiger wird die Situation, wenn Sie sich statt in der Textkonsole mit einem Display-Manager anmelden. Ob auf der grafischen Oberfläche des Desktops ein xterm mit der Bash als Login-Shell läuft, hängt unter anderem von den Einstellungen des Window Managers ab, mit dem Sie X-Programme starten.
Der sicherste Weg, um an eine Login-Shell zu kommen, ist der Aufruf eines Xterms mit der Option -ls. Änderungen, die Sie während der Laufzeit der Shell an der Konfiguration durchführen, werden natürlich erst wirksam, nachdem Sie die Datei mit dem Aufruf source erneut einlesen. Das geht beispielsweise so:
[root] # source /etc/profile
Das gilt freilich nicht unter X, wenn in einer Terminal-Emulation noch eine Shell offen steht. Sie bleibt von der neuen Konfiguration unberührt und arbeitet weiterhin mit den alten Einstellungen. Der sicherste Weg ist, die grafische Oberfläche zu verlassen, um sich danach erneut einzuloggen.
Automatisierte Anweisungen wie das Löschen von Backup-Dateien, die die Bash beim Ausloggen ausführen soll, gehören übrigens in die Datei ~/.bash_logout. So viel zur Login-Shell, deren Möglichkeiten sich hiermit zwar nicht erschöpfen, aber den Rahmen dieses Artikels sprengen.
Sie werden es erraten haben: Es gibt auch Nicht-Login-Shells. Anweisungen für diese Art der Bash sollten normalerweise in die Datei ~/.bashrc geschrieben werden. Allerdings darf man sich darauf nicht verlassen, da viele Distributionen die Datei auch bei Login-Shells einlesen.
Vermutlich ist die Bash bereits durch die Konfiguration als Login-Shell so gut eingerichtet, dass weitere Einstellungen in ~/.bashrc nicht zwingend notwendig sind. Und nun beginnt das Verwirrspiel der Distributoren, das wir am Beispiel der Nürnberger SuSE festmachen.
Bereits im Kopf der /etc/profile werden Sie vom Distributor darauf hingewiesen, diese Datei nicht zu editieren. Von Ihnen gestaltete, globale Einstellungen müssen Sie in die Datei /etc/profile.local schreiben. Der Hintergrund ist, dass /etc/profile durch ein System-Update oder die Arbeit mit dem SuSE-eigenen Tool YaST überschrieben werden kann.
Aber damit nicht genug: In /etc/profile werden zudem die Dateien /etc/profile.dos, /etc/SuSEconfig/profile und alle Dateien im Verzeichnis /etc/profile.d eingelesen.
Daher ist dem unerfahrenen Anwender nur zu raten, die Finger von diesen Dateien zu lassen. Mit der Zeit und einiger Erfahrung können diese Strukturen aufgebrochen und klarer geordnet werden.
Variablen und Umgebungen
Bisher haben wir uns mit den Dateien der Konfiguration beschäftigt. Nun ist es an der Zeit, dass wir uns deren Inhalt genauer ansehen. Ein Funktion, die der Anwender häufig setzt, ist der alias. Mit alias definieren Sie ein Kommando, um eine umfangreiche Eingabe abzukürzen:
[andreas]~ > alias gnus='xemacs -nw -f gnus'
Mit dem obigen Befehl erstellen Sie die Abkürzung gnus, mit der Sie ohne viel Tipperei den Newsreader Gnus in der Textkonsole starten. Selbstverständlich dürfen sie verschiedene Kommandos, durch Strichpunkte getrennt, zu einem Befehl zusammenfassen:
[andreas]~ > alias unmount='cd;umount /media/cdrom;eject'
Ein unmount in der Kommandozeile führt ab jetzt dazu, dass Sie ins Home-Verzeichnis wechseln (cd). Danach wird das Medium im CD-ROM-Laufwerk ausgehängt (umount /media/cdrom) und die CD ausgeworfen (eject).
Verzichten müssen Sie auf ein alias, das Sie auf die Parameter eines Programmes anwenden:
[andreas]~ > alias option='-fn lucidasanstypewriter-14' [andreas]~ > xterm option xterm: bad command line option "option"
Da dieser Versuch einer Alias-Belegung nicht funktioniert, löschen wir die entsprechende Abkürzung:
[andreas]~ > unalias option
Ein alleinstehendes alias zeigt eine alphabetisch geordnete Liste der Eingabekürzel. Da wir kein alias option=… darunter finden, haben wir es erfolgreich getilgt:
[andreas]~ > alias alias newart='vim ~/work/artikel/newart.txt' alias nhol='sudo /usr/local/sbin/fetchnews -vvv' alias o='less' alias rd='rmdir'
Um den entsprechenden Abkürzungen Dauer zu verleihen, tragen Sie sie in ~/.bashrc oder ~/.profile ein.
Weiter oben haben wir die Umgebungsvariablen bereits angeschnitten. Die Variablen werden an Kommandos und Programme weitergegeben und bilden deren Umgebung, in der sie bestimmte Werte finden, wie beispielsweise den Standard-News-Server. Was das bedeutet, wollen wir uns anhand eines Beispiels klar machen.
In Mutt, einem Mail-Programm für die Textkonsole, schreiben Sie Ihre Nachrichten mit einem externen Editor. Der Mailer zieht die Information, welches Ihr Standard-Editor ist, unter anderem aus der Variablen EDITOR. Sie können selbst nachsehen, welcher Wert dort zugewiesen wurde:
[andreas]~ > echo $EDITOR /usr/bin/vim
Weitere wichtige Umgebungsvariablen sind PATH und MANPATH. PATH enthält den Suchpfad aller ausführbaren Dateien. Sobald Sie in der Bash ein Programm aufrufen, durchsucht die Shell die Verzeichnisliste der Variable nach dem Befehl. Sobald sie den gewünschten Eintrag gefunden hat, bricht sie die Suche ab und führt das Kommando aus.
Es ist also nicht gleichgültig, wo sich ein Verzeichnis in PATH befindet. MANPATH hingegen reiht die Pfade zu den Manual-Seiten auf. Wenn Sie jetzt neugierig geworden sind, liefern Ihnen die Kommandos export und printenv eine schier unendliche Liste der Umgebungsvariablen.
Es ist nicht schwer, Umgebungsvariablen in eigener Regie zu erstellen. In der Regel kommt dabei der Befehl export zum Einsatz. Unseren Testballon starten wir mit der Variable PS1. Sie beinhaltet die Zeichenkette zur Prompt-Einstellung. Der Prompt, auch Eingabeaufforderung genannt, ist der Teil der Kommandozeile, hinter dem Sie Ihre Befehle tippen. Auch er kann Sie mit nützlichem Hintergrund versorgen:
[andreas]~ > export PS1='\u um \t auf \h in \w \$ ' andreas um 09:29:02 auf comone in ~ $
Wie Sie sehen, hat unser Prompt die Form geändert. Das \u bildet den User-Namen ab, \t zeigt die aktuelle 24-Stunden-Zeit, \h informiert über den Rechnernamen, \w steht für das aktuelle Verzeichnis, und \$ ist der Prompt-Abschluss. Wem das zu unübersichtlich ist, der beschränkt sich auf den User-Namen und hebt ihn farbig hervor. Um diese Aufgabe zu meistern, bedienen wir uns des Escape-Zeichens \e und so genannten Escape-Sequenzen:
[andreas]~ > export PS1='\e[32m\u\e[0m \$ '
Das Ergebnis ist ein grüner Prompt, mit dem Sie auch in einer dicht beschriebenen Bash den Durchblick behalten. Umfangreiches Material zum Thema Escape-Sequenzen entdecken Sie im Archiv der Schwesterzeitschrift Linux-Magazin [1] oder mit dem Befehl man console_code.
Tragen Sie nun die Eingabeaufforderung, die Ihnen gefällt, beispielsweise in die Dateien /etc/profile oder ~/.bash_profile ein, um sie ständig zur Verfügung zu haben:
PS1='\w \$' export PS1
Sie sehen: Die Bash ist kein Mysterium oder Hacker-Tool, sondern ein flexibles Programm, um den Alltag am Computer mit Komfort zu meistern.
Infos
[1] Peter Kruse: “Farbiger Prompt”, http://www.linux-magazin.de/Artikel/ausgabe/1999/02/Prompt/prompt.html







