Fortsetzungsroman

Ein beliebtes Feature der Bourne Again Shell bash ist die automatische Vervollständigung - neudeutsch „Completion“ - von Dateinamen und Kommandos. Richtig komfortabel lässt es sich mit der Ergänzungsfunktion arbeiten, wenn man sie nach seinen eigenen Vorstellungen programmiert.

In Pocket speichern vorlesen Druckansicht 6 Kommentare lesen
Lesezeit: 4 Min.
Von
  • Michael Riepe

Nicht nur tippfaule Anwender wissen zu schätzen, dass ihnen die Bash per Druck auf Tab mögliche Fortsetzungen des gerade begonnenen Kommandos anbietet.

In der Standardeinstellung zieht bash als Ergänzungen allerdings nur Dateinamen in Betracht. Verlangt ein Kommando als Argument etwa die Nummer eines Prozesses oder den Namen eines Benutzers, hilft der Druck auf Tab nicht weiter. Lässt der Nutzer andererseits das Kommando cd vervollständigen, zeigt die Shell als Ergänzungen nicht nur die gewünschten Verzeichnisse an, sondern auch alle übrigen Dateien. Komfortabler und übersichtlicher ist eine Ergänzungsfunktion, die das eingetippte Kommando berücksichtigt.

Mit dem eingebauten Befehl complete kann der Nutzer einstellen, welche Ergänzungen die Shell zu einem Kommando anbietet. complete -d cd pushd rmdir etwa teilt der Bash mit, dass die Befehle cd, pushd und rmdir als Argumente die Namen von Verzeichnissen erwarten. Analog lässt sich die Auswahl auf Befehle (-c), Dateien (-f) oder die Namen von Gruppen (-g), Nutzern (-u) und Shell-Variablen (-v) einschränken. Kombiniert man mehrere Optionen, zeigt die Shell alle Ergänzungen an, die eins der Kriterien erfüllen.

Noch mehr Kategorien lassen sich mit der Option -A auswählen. Eine komplette Liste ist in der Manpage oder der Texinfo-Dokumentation zur Bash zu finden.

Nur wenige Kommandos - etwa cp, mv oder rm - lassen sich auf alle Dateien anwenden. Meist empfiehlt es sich daher, die Auswahl weiter einzuschränken. Einen einfachen Filter kann der Nutzer mit der Option -X hinzufügen: -X ’*~’ etwa entfernt alle Dateien aus der Liste, deren Name mit einer Tilde endet - einige Programme kennzeichnen damit automatisch angelegte Backup-Dateien. Wer einen „positiven“ Filter benötigt, muss dem Ausdruck ein Ausrufezeichen voranstellen: -X ’!*.txt’ etwa lässt nur Ergänzungen zu, die auf „.txt“ enden. Taucht das Zeichen & im Muster auf, ersetzt die Shell es durch den eingetippten Wortanfang. Soll sie es hingegen wörtlich nehmen, muss der Nutzer einen Backslash davorsetzen.

Leider lässt die Filter-Syntax keine komplizierteren Ausdrücke zu, von Regular Expressions ganz zu schweigen. Kaskadieren lassen sich die Filter ebenfalls nicht: Stehen mehrere in der Kommandozeile, beachtet complete lediglich den letzten. Wer etwa nur Dateien mit den Endungen .txt und .doc als Ergänzungen sehen möchte, muss einen anderen Weg gehen.

Mit -F kann der Anwender den Namen einer selbst geschriebenen Shell-Funktion an complete übergeben. Sie muss eine Liste der Ergänzungen zusammenstellen und in der Array-Variablen COMPREPLY zurückgeben (siehe Listing 1).

Mehr Infos

Listing 1

complete_beispiel() {
local file
for file in *.doc *.txt
do test -e "$file" && COMPREPLY=("${COMPREPLY[@]}" "$file")
done
}
complete -F complete_beispiel beispiel

Den Inhalt der Kommandozeile kann die Funktion den von der Shell bereitgestellten Variablen entnehmen.

Allerdings berücksichtigt die relativ naive Implementierung noch nicht den eingegebenen Text: Hat der Nutzer schon einen Teil des Namens getippt, soll die Funktion nur dazu passende Ergänzungen liefern. Dazu kann sie sich der Variablen COMP_LINE und COMP_POINT bedienen: Sie enthalten den momentanen Inhalt der Kommandozeile und die Position des Cursors.

Außerdem zerlegt die Shell die Kommandozeile in ihre Bestandteile und speichert diese in der Array-Variablen COMP_WORDS. COMP_CWORD enthält die Nummer des Worts, auf das der Cursor zeigt. Listing 2 demonstriert einen einfachen Weg, die Variablen einzusetzen. Alternativ kann die Funktion ihre Argumente auswerten: $1 enthält den Namen des Befehls, $2 das zu ergänzende Wort und $3 das Wort direkt davor.

Mehr Infos

Listing 2

complete_beispiel_2() {
local anfang="${COMP_WORDS[$COMP_CWORD]}"
local file
for file in "$anfang"*.doc "$anfang"*.txt
do test -e "$file" && COMPREPLY=("${COMPREPLY[@]}" "$file")
done
}

Mit einer selbst geschriebenen Funktion kann der Nutzer den Inhalt der Ergänzungsliste frei wählen.

Selbst programmierte Ergänzungen müssen sich nicht auf Dateinamen und Verzeichnisse beschränken. Nach einem Minuszeichen etwa könnte die Shell geeignete Optionen für einen Befehl vorschlagen. Bei Programmen mit komplexer Syntax - etwa cvs - könnte die Ergänzungsliste die zum jeweiligen Kontext passenden Elemente enthalten. Außerdem ließe sich die Ergänzungsfunktion so erweitern, dass sie nach bestimmten Eingaben - etwa einem Fragezeichen - einen Hilfetext ausgibt. Wer damit experimentieren möchte, findet weitere Informationen im Abschnitt „Programmable Completion“ der Bash-Dokumentation. (mr)