Bash Completion in eigenen Skripten einsetzen
Die Bash Completion erlaubt es durch das betätigen der Tab-Taste Befehle, Dateipfade und Optionen zu vervollständigen um unnötiges Tippen zu ersparen. In diesem Artikel wird gezeigt, wie die Vervollständigung von Optionen für eigene Skripte genutzt werden kann.
Voraussetzung ist das bash-completion
installiert ist:
apt install bash-completion
Szenario
Nehmen wir an wir haben ein Skript bash_completion_test.sh und wollen, dass die Optionen hier, haus und katze vervollständigt werden.
Statische Optionen
Es wird nun eine neue Datei mit dem Namen des Skriptes in /etc/bash_completion.d angelegt: /etc/bash_completion.d/bash_completion_test.sh
_bash_completion_test()
{
local cur prev opts
COMPREPLY=()
cur="${COMP_WORDS[COMP_CWORD]}"
prev="${COMP_WORDS[COMP_CWORD-1]}"
opts="hier haus katze"
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
return 0
}
complete -F _bash_completion_test bash_completion_test.sh
Dabei sollte beachtet werden dass
- der Name der Bash-Funktion der gleiche seien sollte wie der Name des Skriptes, dass vervollständigt werden soll und mit einem Unterstrich beginnt (da Punkte nicht erlaubt sind wurde die Endung .sh weggelassen)
- in der Variable opts alle möglichen Werte für die Vervollständigung stehen
- hinter complete -F (letzte Zeile) der Name der Bash-Funktion und direkt dahinter der Name des Skriptes eingetragen wird
Nach einem erneuten sourcen der Datei /etc/bash_completion bzw. einem Re-Login sollte nun die Vervollständigung funktionieren.
root@test:~# bash_completion_test.sh # [TAB][TAB]
haus hier katze
root@test:~# bash_completion_test.sh h # [TAB][TAB]
haus hier
root@test:~# bash_completion_test.sh ha # [TAB]
root@test:~# bash_completion_test.sh haus
Dynamische Optionen
Der Inhalt der Variable opts muss nicht statisch angegeben sondern kann auch Skript-typisch dynamisch erzeugt werden. Folgendes würde z.B. als mögliche Werte für die Vervollständigung alle Ordner und Dateien des Verzeichnisses /etc festlegen:
opts="$(ls /etc)"
Es sollte beachtet werden, dass die Ausführung der Befehle relativ schnell gehen und nicht mehrere Sekunden dauern, da diese Verzögerungen direkt bei der Vervollständigung weitergegeben werden.
Vervollständigung von Unteroptionen
Will man abhängig von der vorher eingegebenen Option andere Vervollständigungen nutzen kann folgendes verwendet werden:
_bash_completion_test()
{
local cur prev opts base
COMPREPLY=()
cur="${COMP_WORDS[COMP_CWORD]}"
prev="${COMP_WORDS[COMP_CWORD-1]}"
opts="hier haus katze"
### erweiterte Vervollstaendigung ###
case "${prev}" in
haus)
local stockwerk="dachgeschoss erdgeschoss keller"
COMPREPLY=( $(compgen -W "${stockwerk}" -- ${cur}) )
return 0
;;
katze)
local koerperteile="pfote auge schwanz"
COMPREPLY=( $(compgen -W "${koerperteile}" -- ${cur}) )
return 0
;;
*)
;;
esac
COMPREPLY=($(compgen -W "${opts}" -- ${cur}))
return 0
}
complete -F _bash_completion_test bash_completion_test.sh
Mit der Variable prev wird das vorherige Wort kontrolliert und über ein Case-Statement abhängig von dem Ergebnis andere Vervollständigungen gesetzt. Dazu wurden jeweils neue lokale Variablen mit den dazugehörigen Werten erstellt. Diese neuen Variablen (hier stockwerk und koerperteil) werden bei der Vervollständigung (compgen Befehl) anstelle von opts benutzt.
Das angegebene Skript würde zu folgendem Ergebnis führen:
root@test:~# bash_completion_test.sh # [TAB][TAB]
haus hier katze
root@test:~# bash_completion_test.sh h # [TAB][TAB]
haus hier
root@test:~# bash_completion_test.sh ha # [TAB]
root@test:~# bash_completion_test.sh haus # [TAB][TAB]
dachgeschoss erdgeschoss keller
root@test:~# bash_completion_test.sh katze # [TAB][TAB]
auge pfote schwanz
root@test:~# bash_completion_test.sh hier # [TAB][TAB]
haus hier katze