Aus Linux-Magazin 01/2012

Shellskripte aus der Stümper-Liga – Folge 18: Bash Completion

Über Klicki-Bunti und grafische Oberflächen sollten Kommandozeilen-Fans gerechterweise nur dann die Nase rümpfen, wenn sie die Effizienz steigernden Bedienungstricks der interaktiven Shell auch wirklich kennen und benutzen. Diesmal: Bash Completion.

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 DateiZielr[Esc][Alt Gr]+[Q]

Das ergänzt die Bash dann zu

scp DateiZielrechner

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.

Listing 1

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.

Selbst ist der Basher

Zum Glück muss der User für die Standardkommandos nicht selbst in die Tasten greifen und »complete« -Definitionen schreiben. Open Suse zum Beispiel installiert ein ganzes Complete-Framework. Eine Alternative ist das umfangreiche »Bash-Completion« -Paket, das beispielsweise für GNU-kompatible Tools alle CLI-Optionen komplettiert (Abbildung 1), gültige Paketnamen für das RPM-Kommando vervollständigt oder die Module in CVS intus hat. Wer selbst tunen möchte, findet im Bash-Completion-Paket genug Anwendungsbeispiele Funktion.

Abbildung 1: Completion vervollständigt die Programmoptionen von »grep«.

Abbildung 1: Completion vervollständigt die Programmoptionen von »grep«.

Fazit

Dass die Bash dem Anwender als Programmiersprache ein ausgeklügeltes (und nicht immer selbsterklärendes) Werkzeug in die Hand drückt, hatten frühere “Bash Bashing”-Folgen bereits bewiesen.

Die diesmal beschriebene Auto-Vervollständigung legt nahe, dass auch der interaktive Modus der Shell sehr mächtige Funktionen bereithält. Wer ein kleines Cheat-Sheet [1] mit den wichtigsten Funktionstasten neben den PC legt, kann nach und nach das Klappern der Tastatur reduzieren.

Infos

  1. Tastatur-Belegung mit wichtigen Bash-Kommandos: http://weblog.topopardo.com/others/bash_cheat_sheet.pdf

Der Autor

Bernhard Bablok betreut bei Allianz Managed & Operations Services SE ein großes Datawarehouse mit technischen Performancemessdaten von Mainframes bis zu Servern. Wenn er nicht Musik hört, mit dem Fahrrad oder zu Fuß unterwegs ist, beschäftigt er sich mit Themen rund um Linux und Objektorientierung. Er ist unter mailto:mail@bablokb.de zu erreichen.

LINUX-MAGAZIN KAUFEN
EINZELNE AUSGABE Print-Ausgaben Digitale Ausgaben
ABONNEMENTS Print-Abos Digitales Abo
TABLET & SMARTPHONE APPS Readly Logo
E-Mail Benachrichtigung
Benachrichtige mich zu:
0 Kommentare
Älteste
Neuste Beste Bewertung
Inline Feedbacks
Alle Kommentare anzeigen
Nach oben