![]() |
|
||||||||||||||||||
|
|||||||||||||||||||
|
|||||||||||||||||||
|
||
|
TFT Monitor bei
Mercateo kaufen.
Neues Netbook? Ein Preisvergleich lohnt sich. Bei uns finden sie Notebooks, PDAs und Drucker mit Testberichten und Tipps. Diamant Buchhaltungssoftware – transparent und detailliert auch für die Konzernbuchhaltung. Günstige Shareware Programme als direkte Downloads im Software Portal. Bis zu 70% sparen durch Preisvergleich. |
||
|
Im letzten Teil dieser Serie haben wir verschiedene Möglichkeiten diskutiert, um Befehlszeilen mehr oder weniger unter Zuhilfenahme interner Funktionen der Bash (genauer: der Readline-Library) aus den Informationen zu konstruieren, die der Shell intern zur Verfügung stehen. Eine Zusammenfassung der wichtigsten Tastenkombinationen zeigt Tabelle 1. Besonders die unterschiedlichen Mechanismen der Komplettierung (dem automatischen Ergänzen teilweise eingegebener Zeichenketten) sind sehr nützlich und sparen dem Anwender viele Tastendrücke. Diesmal soll mit der »History« ein weiteres, effektives Hilfsmittel zur Eingabe und Bearbeitung von Befehlszeilen vorgestellt werden. Die Funktionen für diesen Einsatzzweck sind in der GNU-History-Library (/lib/libhistory.so) zusammengefaßt.
|
Emacs-Modus: Die Eingabe der Bash kann in zwei unterschiedlichen
»Stilrichtungen« - den Modi - erfolgen. Neben dem voreingestellten Emacs-Modus (der sich an den Gepflogenheiten dieses Editors orientiert) kann auch der VI-Editor imitiert werden. So ist sichergestellt, daß geübte Anwender sehr effektiv mit der Bash arbeiten können und nicht versehentlich falsche Tastenbefehle benutzen, die sie von ihrem Editor gewohnt sind. Die Eingabemodi werden mit dem Befehl
$> set -o vi in den VI-Modus bzw. durch
$> set -o emacs zurück in den Emacs-Modus geschaltet. |
Alle Befehlszeilen werden in einer speziellen Datei - der History-Datei - gespeichert. Diese History-Datei stellt damit zum einen eine Art Logbuch dar, anhand dessen Einträge der Anwender sich vergegenwärtigen kann, welche Aktionen bereits ausgeführt wurden; andererseits ermöglicht sie das »Lernen aus der Vergangenheit«. Eine gute Lösung, die in Form von mehreren Befehlszeilen in der History-Datei vorhanden ist, kann mit wenig Aufwand in ein Shell-Programm (Script) umgesetzt werden.
Die vorhergehenden Befehlszeilen haben übrigens auch für die Konstruktion neuer Zeilen eine besondere Bedeutung. Oftmals sind Eingaben wie die folgenden zu beobachten:
$> ls /usr/share/info ... bash.info fileutils.info libg++.info-4 ... $> cp /usr/share/info/bash.info . $> emacs /usr/share/info/bash.info $> info /usr/share/info/bash.info
In diesen Befehlszeilen entspricht mindestens ein Argument in der aktuellen Befehlszeile einem der vorhergehenden, bzw. bezieht sich darauf. In den meisten Fällen handelt es sich um das letzte Argument der vorhergehenden Befehlszeile. Anwender können sich mit einer ganz einfachen Tastenkombination hier erheblichen Tippaufwand ersparen:
$> ls /usr/share/info ... $> cp [META][.] /usr/share/info/ba[Tab]sh.info ...
Durch die Tastenkombination [Meta]+[.] fügt der Bashzeileneditor automatisch das letzte Argument der vorherigen Befehlszeile an der aktuellen Position ein. (Nochmals zur Erinnerung: Die Meta-Taste wird auf den normalen Keyboards durch die linke Alt-Taste emuliert oder alternativ durch das Drücken der Esc-Taste vor der Eingabe der zweiten Taste.) Die verwendete Readline-Funktion heißt insert-last-argument. Für Spezialisten: Beim Übergang von der zweiten (cp ...) zur dritten Zeile (emacs ..) wird aber nicht das letzte, sondern das vorletzte (das in der Befehlszeile erste) Argument benötigt. Auf dieses kann ganz einfach mit der Funktion yank-nth-arg zugegriffen werden, die an die Tastenkombination [Meta-Control-y] gebunden ist. Die Zählweise der Bash beginnt hierbei mit dem 0ten Argument (dem Befehl) an der ersten Position in der Befehlszeile.
Ein zweiter, sehr nützlicher Mechanismus wird als »Quick-Substitution« bezeichnet und verwendet ebenfalls die Informationen aus der letzten Befehlszeile. In manchen Situationen ändern sich aufeinanderfolgende Befehlszeichen nur geringfügig:
$> ls ~/test -r $> rm ~/test -r
In diesem Fall kann die zweite Befehlszeile aus der ersten konstruiert werden, indem »ls« durch »rm« ausgetauscht wird. Genau dies ermöglicht die Quick-Substitution:
$> ls ~/test/ -r $> ^ls^rm[Return] rm ~/test/ -r rm: in Verzeichnis »test« absteigen?
Die Substitution ist nicht auf die Befehle in der Befehlszeile beschränkt:
$> ls ~/test/ -r $> ^st^st1[Return] ls ~/test1/ -r ...
Jede beliebige Zeichenfolge kann ausgetauscht werden, allerdings wird nur das erste Auftreten der Zeichen ersetzt.
Die Befehlszeilenhistory (so der korrekte Name) ist zu jedem Zeitpunkt über die Aufwärts-Pfeil-Taste [Cursor hoch] erreichbar. Jede Betätigung dieser Taste holt eine weitere zuvor ausgeführte Befehlszeile zurück. Diese Befehlszeilen können normal editiert werden, die Return-Taste führt die aktuelle Zeile - so wie sie momentan dargestellt wird - aus. Auch das Scrollen in die Gegenrichtung ist möglich: Sind Sie durch allzu heftigen Einsatz der Aufwärts-Pfeil-Taste zu weit in die Geschichte eingetaucht, dann können Sie mit der Abwärts-Pfeil-Taste wieder in Richtung Gegenwart wandern.
Die Befehlszeilenhistory wird von der Bash in Form einer Datei gespeichert. Die Bash legt diese Datei im Home-Verzeichnis unter dem Namen .bash_history automatisch an oder, sofern diese Datei bereits existiert, liest sie sie beim Start ein. In dem zweiten Fall wird damit der Inhalt der Datei automatisch in den eingebauten Historybuffer der Bash kopiert. Damit sind die Zeilen über die Cursortasten erreichbar.
Untersuchen Sie einmal, ob sich diese Datei bei Ihnen anfindet. Sie hat etwa folgenden Aufbau:
ps x | grep xemacs
kill -HUB 1325
kill -1 1321
ll -rt
xemacs
bg
ls -rt
wipe ~/del_me
...
Es handelt sich dabei um eine einfache Textdatei, die mit jedem Editor oder Pager (Seitenanzeigeprogramm à la more und less) angezeigt werden kann.
Einige der wichtigsten Funktionen zur Verwaltung der History-Datei ermöglichen das Suchen im Historybuffer.
In vielen Situationen erinnert sich der Anwender, daß er zuvor bereits einmal eine bestimmte Befehlszeile ausgeführt hat, weiß aber oft nicht mehr, wann das war. Und gerade diese Befehlszeile wäre jetzt so nützlich! In diesem Fall hat er die Möglichkeit, den Historybuffer zu durchsuchen. Dazu stellt die Bash ihm mehrere Funkionen zur Verfügung.
Die am meisten verwendete Methode wird als »inkrementale« Suche bezeichnet. Bei dieser Form der Suche zeigt die Bash immer das Ergebnis automatisch an, ohne daß dazu eine weitere Bestätigung notwendig wäre. Die Tastenkombination [Control-r] aktiviert die dabei eingesetzte Funktion reverse-search-history. Ein Beispiel zeigt den Einsatz dieser Funktion. Würde in der oben gezeigten History nach der Befehlszeile nach der Zeile mit dem Befehl xemacs gesucht werden, so reicht es aus, »x« einzugeben.
$> [Control-r]
(reverse-i-search)`x': xemacs
Die letzte der beiden kill-Zeilen wird durch Eingabe eines »k«'s gefunden. Gäben Sie aber statt dessen ein »i« ein, landen Sie in der wipe-Zeile. Von hier können Sie durch einen weiteren Buchstaben »l« weiter rückwärts durch den Historybuffer streifen.
$> [Control-r]
(reverse-i-search)`i': wipe ~/del_me
(reverse-i-search)`il': kill -1 1321
Auf diese Weise wird die Zielzeile durch jedes zusätzliche Zeichen genauer spezifiziert. Sobald die richtige Zeile dargestellt wird, können Sie die Suche mit [ESC] beenden, die angezeigte Befehlszeile mit [Return] ausführen, durch [Control-a] an den Anfang oder mit [Control-e] an deren Ende springen. Wie findet man aber Zeilen, die sich wie die kill-Zeilen nur in wenigen Zeichen voneinander unterscheiden? Hier greift der Vorteil der inkrementalen Suche erst sehr spät. Daher gibt es die Möglichkeit, bei der inkrementalen Suche eine angezeigte Zeile durch erneute Eingabe von [Control-r] zu überspringen, ohne daß die bereits eingegebenen Suchzeichen verloren gehen.
$> [Control-r]
(reverse-i-search)`il': kill -1 1321
[Control-r]
(reverse-i-search)`il': kill -HUB 1325
In die Gegenrichtung (zum Ende des Historybuffers hin) wird die Funktion forward-search-history eingesetzt, die gewöhnlich an die Tastenkombination [Control-s] gebunden ist. Dabei tritt bei vielen Terminals ein Problem auf: durch [Control-s] wird voreinstellungsgemäß das Terminal gesperrt. Mit dem Befehl stty (Set Tele Typewriter) kann diese Voreinstellung aber angezeigt und leicht modifiziert werden:
$> stty -a
speed 9600 baud; rows 77; columns 80; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undefiniert>;
eol2 = <undefiniert>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R;
werase = ^W; lnext = ^V; flush = ^O; min = 1; time = 0;
-parenb -parodd cs8 -hupcl -cstopb cread -clocal -crtscts
-ignbrk brkint ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff
-iuclc -ixany imaxbel
opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt
echoctl echoke
Die problematische Einstellung wurde fett hervorgehoben. Eine einfache
Rekonfiguration reicht aus, um derartige Probleme zu beheben:
$> stty stop ^p
$> stty stop ^Q
Die erste Zeile sollte bei allen Terminals funktionieren. Nach dem Ausführen dieser Befehlszeile sollte über [Control-s] die Suchfunktion zur Verfügung stehen (erkennbar an der Ausgabe von (i-search)`': unter der Befehlszeile) und die Terminalausgabe wird nun durch [Control-p] angehalten. Bei einigen Terminals kann mit der zweiten Variante eine Umschaltfunktion durch [Control-q] realisiert werden. Erfolgt eine Terminalausgabe, dann stoppt [Control-q] diese. Ein erneutes Eingeben dieser Tastenkombination startet die Ausgabe wieder. Die entsprechende Befehlszeile sollte beim Aufruf der Bash automatisch ausgeführt werden. In einem der nächsten Teile werden wir dazu verschiedene Möglichkeiten vorstellen. Hier zunächst nur soviel: fügen Sie die Befehlszeile am Ende der Dateien .bashrc, .bash_profile oder .bash_login ein, je nach dem, welche Dateien vorhanden sind.
Die nicht-inkrementalen Suchfunktionen werden bei der Bash selten verwendet. Sie sind daher oft gar nicht an Tasten gebunden. Sie funktionieren wie gewohnt: die Suche beginnt erst nach der Eingabe eines Suchbegriffs. Eine Ausnahme gibt es: Mit der Funktion character-search springt der Cursor zum nächsten Auftreten des Zeichens in der Befehlszeile, auf dem er momentan steht. Diese Funktion ist gewöhnlich an [Control-]] gebunden. In die Gegenrichtung sucht man durch [Meta-Control-]].
Für die Verwaltung des Historybuffers und der History-Datei verfügt die Bash über einen eingebauten Befehl mit dem Namen history.
Mit ihm werden alle wichtigen Aktionen ausgelöst bzw. gesteuert. Optionen steuern wie üblich die Funktionalität des Befehls, ohne Optionen und Argument listet er den aktuellen Inhalt des Historybuffers:
$> history
...
939 less ~/.bash_history
940 stty -a
941 stty stop ^Q
942 stty stop ^p
943 man readline
944 latex bash-history
...
Folgt dem Befehl ein numerisches Argument (eine Zahl), dann bestimmt diese, wieviele Zeilen ausgegeben werden.
$> history 3
942 stty stop ^p
943 man readline
944 latex bash-history
$HISTSIZE: Die Anzahl der Zeilen, die im Historybuffer gespeichert werden können. Voreingestellt sind 500 Zeilen. Die Eingabe der 501ten Zeile bewirkt, daß die 1te Zeile aus den Historybuffer verschwindet. Um den voreingestellten Zeilenspeicher zu verdoppeln reicht die folgende Befehlszeile aus:
$> export HISTSIZE=1000
$HISTFILE: Name und Pfad der Datei zum Speichern des Historybuffers (der History-Datei). Voreingestellt ist die Datei .bash-history im Home-Verzeichnis des Anwenders. Die Bash speichert den Inhalt des Historybuffers nicht ab, wenn diese Variable nicht gesetzt wurde.
$HISTFILESIZE: Die maximale Anzahl von Zeilen, die in der History-Datei gespeichert werden sollen. Voreingestellt sind 500 Zeilen.
$HISTCONTROL: Mit dieser Variablen wird gesteuert, welche Zeilen im Historybuffer aufgenommen werden. Enthält sie das Schlüsselwort »ignorespace«, dann werden Befehlszeilen, die mit einem Leerzeichen beginnen, ignoriert. Durch »ignoredups« werden Befehlszeilen nur einmal im Historybuffer gespeichert, auch wenn sie mehrmals hintereinander eingegeben wurden. »ignoreboth« kombiniert beide Möglichkeiten. Ist die Variable nicht gesetzt, dann zeichnet die History die Befehlszeilen genau so auf, wie sie eingegeben wurden.
Die folgenden Variablen sind nur für Spezialisten interessant:
$HISTIGNORE: Diese Variable stellt die wohl weitgehendsten Möglichkeiten zur Verfügung, Zeilen von der Aufnahme in den Historybuffer auszuschließen. In ihr können Ausschlußmuster definiert werden. Zeilen, die diesem Muster entsprechen, werden nicht im Historybuffer gespeichert. Mehrere Muster können durch Doppelpunkte getrennt angegeben werden; jedes Muster muß die gesammte Befehlszeile beschreiben. Normalerweise ist diese Variable ungesetzt.
$histchars: In dieser Variablen können bis zu drei Zeichen gespeichert werden, die für die History-Funktion besondere Bedeutung haben: Das erste Zeichen wird zum Einleiten der History-Expandierung verwendet. Voreingestellt ist das Ausrufungszeichen. Das zweite Zeichen dient zur Quick-Substitution. Voreingestellt ist das »Hütchen« (Caret) »^ «. Als drittes kann ein Kommentarzeichen (voreingestellt: #) definiert werden. Alle nach diesem Zeichen auftretenden Zeichen werden in der Befehlszeile ignoriert.
Als letzte ist noch die Variable $HISTCMD zu erwähnen: sie enthält die Nummer der Befehlszeile im Historybuffer.
[Meta][1] [Meta][2] (arg: 12)Bei gleichzeitig gedrückter linker Alt-Taste werden in diesem Beispiel die Ziffern »1« und »2« eingegeben. Der nächste Tastenbefehl wird dadurch 12mal ausgeführt. Nett, oder? Probieren Sie dies einmal in Verbindung mit den History-Funktionen.
Die Verwendung der History ist einfach und komfortabel. Anwender sparen sich viel Tipparbeit (und Zeit), indem sie die Informationen aus der letzten Befehlszeile »recyclen«. Gerade Mechanismen wie die Quick-Substitution oder das Einfügen von Argumenten aus den vorigen Zeilen sollte jeder kennen.
Ein Tip ganz am Rande: Die History zeichnet nur die Befehlszeilen auf. In manchen Situationen ist es aber wünschenswert oder notwendig, auch die Ergebnisse der Aktionen zu protokollieren. Für diesen Einsatz wurde der Befehl script entwickelt. Er wird vor den aufzuzeichnenden Befehlen gestartet. Voreinstellungsgemäß schreibt er alle folgenden Ein- und Ausgaben in der Datei »typescript« mit. Ihm kann ein anderer Dateiname als optionales Argument übergeben werden. Bestehende Typescript-Files werden gelöscht, wenn nicht die Option -a (append) angegeben wird. Beendet wird script durch [Control-d] oder den eingebauten Shellbefehl exit.
$> script »Script« wurde gestartet, die Datei ist typescript $> ... $> exit »Script« wurde beendet, die Datei ist typescript $>
In der typescript-Datei selbst finden sich genaue Angaben über die aufgezeichnete Sitzung:
»Script« wurde gestartet: Wed Jun 21 11:44:45 2000 $>... $>exit »Script« beendet: Wed Jun 21 11:46:29 2000
2
Zilm, Th., Grelck, K.: Linux - die Userreferenz, MITP 1999
Dieser Online-Artikel kann Links enthalten, die auf nicht mehr
vorhandene Seiten verweisen. Wir ändern solche "broken links"
nur in wenigen Ausnahmefällen. Der Online-Artikel soll möglichst
unverändert der gedruckten Fassung entsprechen.
Druckerfreundliche Version |
Feedback zu dieser Seite
|
Datenschutz |
© 2010 Linux New Media AG
[Linux-Magazin]
[LinuxUser]
[EasyLinux]
[Linux-Community]
[Ubuntu User]
[Linux Technical Review]
[Linux Magazine]
[Linux Pro Magazine]
[Ubuntu User]
[EasyLinux Poland]
[Linux Magazine Poland]
[Linux Magazine Brasil]
[EasyLinux Brasil]
[Linux Magazine Spain]