Das Zauberwort, um einerseits die Anzahl der Tastendrücke zu reduzieren und andererseits eventuell folgenreiche Vertipper zu vermeiden, heißt Vervollständigung (Completion). Die [Tab]-Taste schätzt vermutlich jeder Konsolenbenutzer: Sie ergänzt Kommandos am Zeilenanfang sowie Verzeichnis- oder Dateinamen. Die Doppel-[Tab]-Folge kennt mancher nicht, namentlich Linuxer, die solitären Leuchttürmen gleich in einem Meer von Windows-Benutzern stehen. Denen schaut nie ein Gleichgesinnter über die Schulter und sagt: "Spar dir »ls«
-»cd«
-»ls«
…-Orgien, und tippe einfach »cd [Tab][Tab]«
, dann zeigt die Shell eine Liste!"
Vervollständigung ist keine Kernfunktionalität der Bash, sondern der Readline-Bibliothek. Die Readline-Funktion »complete()«
löst das automatische Erweitern eines Textes aus. Sie ist normalerweise an die [Tab]-Taste gebunden. Viele Programme nutzen die Readline-Bibliothek, weshalb der Completion-Mechanismus auch solchen Tools zur Verfügung steht.
Auf der Kommandozeile entscheidend ist der Text vor dem Cursor. Fängt er mit einem Dollarzeichen an, sucht Readline in der Liste der Variablen, bei einer Tilde unter den in »/etc/passwd«
definierten Benutzern und beim Klammeraffen in der Liste der Hosts. Einen Text ohne Sonderzeichen interpretiert die Vervollständigung am Zeilenanfang als Beginn eines Kommandos – inklusive Aliase und Shellfunktionen. Wenn nichts zutrifft, dann versucht die Bash Filename-Completion, das heißt »complete()«
ergänzt den Text durch Datei- oder Verzeichnisnamen im aktuellen Verzeichnis.
Im Hintergrund werkeln für alle diese Vervollständigungen eigene Readline-Funktionen (»complete-command«
, »complete-filename«
, »complete-into-braces«
, »complete-username«
, »complete-hostname«
, »complete-variable«
). Mit
bind -p | grep complete
bekommen Bash-Benutzer zu sehen, an welche Tasten diese Sonderfunktionen auf ihrem System gebunden sind. [Tab] ist nämlich nicht die einzige Taste, die Vervollständigung auslöst. Hostname-Ergänzung erweist sich zum Beispiel als nützlich, wenn man die Hostnamen-Vervollständigung ohne den Klammeraffen benötigt, etwa:
scp Datei Zielr[Esc][Alt Gr]+[Q]
Das ergänzt die Bash dann zu
scp Datei Zielrechner
Die Tastenkombination [Esc][Alt Gr]+[Q], also [Meta][@], ist normalerweise mit »complete-hostname«
verknüpft und ergänzt den Anfang des eingegebenen Hostnamens. Diese Kombination liegt – wie auch ein paar andere – für deutsche Tastaturen recht ungünstig. Profis tragen deshalb in ihre »~/.bashrc«
die Zeile
bind '"\eh": complete-hostname'
ein und nutzen anschließend das leichter erreichbare [Esc][H], was sogar einen Tastenanschlag spart.
Manual führt aufs Glatteis
Sowohl Hostname-Completion als auch User-Completion halten für den Benutzer ein paar Fallstricke bereit. Beispielsweise liest die Bash die Hostnamen aus der Datei, auf die die Variable »HOSTFILE«
zeigt. Laut Bash-Manual bedeutet eine gesetzte, aber leere »HOSTFILE«
-Variable, dass die Bash die »/etc/hosts«
liest. Wenn die Variable nicht gesetzt ist, so ist die Liste für die Vervollständigung leer.
Doch hier irrt das Bash-Manual, genau das Gegenteil ist der Fall: Die Variable muss entweder ungesetzt oder zumindest mit irgendwas gefüllt sein – die »HOSTFILE«
-Datei braucht nicht zu existieren, damit »/etc/hosts«
als Quelle dient. In größeren Umgebungen ist »/etc/hosts«
sowieso meist leer. Hier kann sich jeder Nutzer ein eigenes »HOSTFILE«
mit Favoriten anlegen und die gleichnamige Variable in der »~/.bashrc«
setzen.
User-Completion wertet normalerweise die »/etc/passwd«
aus. In Netzen, die die Benutzernamen in einem Verzeichnisdienst hinterlegen und NSS-LDAP nutzen, löst die Bash bei User-Completion eine LDAP-Anfrage aus. Das kann quälend lange dauern, die Bash scheint einzufrieren. Und: Je nach Größe der Organisation liefert so eine Anfrage sehr viele Benutzernamen zurück, [~][Tab][Tab] beispielsweise fragt alle Nutzer im LDAP ab! Leider gibt es keine zu »HOSTFILE«
äquivanente Umgebungsvariable für die Benutzervervollständigung.
Die eigene Completion
Das Bash-eigene System für die Vervollständigung kann der Benutzer selbst erweitern. Dazu dient unter anderem das Bash-interne Kommando »complete«
. Die Funktion ist nicht ganz trivial, was sich schon an der Ausführlichkeit des Manpage-Abschnittes ablesen lässt. Am einfachsten ist Word-Completion: Ein kleines Synchronisationsskript des Autors nimmt als einziges Argument ein Profil entgegen. Das Kommando
complete -W "home data images baw" syncfiles
sorgt dafür, dass die Bash die möglichen Profilnamen für das Kommando »syncfiles«
automatisch per [Tab] ergänzt. Mächtiger als »-W«
ist die Option »-F«
, die als Argument eine Shellfunktion erwartet. Diese berechnet aus der aktuellen Kommandozeile die möglichen Vervollständigungen und legt sie in dem Array »COMPREPLY«
ab. Das Listing 1 zeigt ein aufs Nötigste reduziertes Beispiel.
Vervollständigung per Shellfunktion
001 #!/bin/bash
002
003 oocalc_complete() {
004 local ext="ods"
005 local word="$2"
006
007 # Standard-Vervollständigung (filename-completion)
008 local i=0 line
009 declare -a liste
010 while read line; do
011 liste[i++]="$line"
012 done < <(compgen -f -- "$word")
013
014 # Filtern: Nur Dateinamen mit der richtigen Extension
015 local w e
016 for w in "${liste[@]}"; do
017 if [ -d "$w" ]; then
018 continue
019 else
020 e="${w##*.}"
021 if [ "$e" = "$ext" ]; then
022 COMPREPLY[i++]="$w"
023 fi
024 fi
025 done
026 }
027
028 complete -o plusdirs -F oocalc_complete oocalc
Die vorliegende Complete-Spezifikation sorgt dafür, dass Bash für das »oocalc«
-Kommando nur Verzeichnisse und ODS-Dateien vervollständigt. Zuerst erzeugt die Shellfunktion in den Zeilen 8 bis 12 eine Liste mit allen Dateien und Verzeichnissen, die eine normale Vervollständigung erfassen würde. Danach filtert das Skript alle Verzeichnisse und unpassenden Dateien heraus. Gültige Vervollständigungen landen in Zeile 22 im Array »COMPREPLY«
. Solche Klimmzüge sind leider notwendig, da die »complete«
-Standardoptionen »-X«
und »-G«
leider nur fürs Filtern von Dateinamen gedacht sind und nicht mit der Autovervollständigung von Verzeichnisnamen zusammenspielen.