Komfortfunktionen der Bash — History, Tab-Completion und Aliases
Was dich erwartet
Die Bash ist auf den ersten Blick eine nüchterne Befehlszeile. Wer aber ihre Komfortfunktionen kennt, arbeitet damit schneller als mit jeder grafischen Oberfläche. Tab-Completion verhindert Tippfehler, die Command History erspart das Wiedertippen langer Befehle, und Aliases kürzen wiederkehrende Kommandos auf zwei Buchstaben ab. Dazu kommen Wildcards für flexible Dateioperationen, Pipes für die Verbindung von Werkzeugen und Tastenkürzel, die den Cursor blitzschnell durch die Zeile bewegen. Dieser Artikel erklärt alle diese Funktionen mit konkreten Beispielen — so wie sie im Alltag tatsächlich vorkommen.
Tab-Completion: Befehle und Pfade automatisch vervollständigen
Tab-Completion ist wahrscheinlich das erste Feature, das Bash-Einsteiger wirklich lieben lernen. Drückst du Tab, vervollständigt die Shell den angefangenen Befehl, Dateinamen oder Verzeichnispfad automatisch — vorausgesetzt, die Eingabe ist eindeutig. Das verhindert Tippfehler und spart bei langen Pfadnamen erheblich Zeit.
Grundprinzip
Tippe die ersten Buchstaben eines Befehls oder Pfades und drücke Tab:
$ ls /etc/netw[Tab]
$ ls /etc/network/
Ist die Eingabe nicht eindeutig — es gibt also mehrere mögliche Treffer — passiert beim ersten Tab-Druck nichts. Drückst du ein zweites Mal, zeigt die Bash alle Optionen an:
$ ls /etc/net[Tab][Tab]
netplan/ network/ networkd-dispatcher/ networks
Das gilt ebenso für Befehlsnamen: sys[Tab][Tab] listet alle Befehle auf, die mit sys beginnen. Tab-Completion greift dabei auf den $PATH zurück und kennt nur tatsächlich installierte Programme.
Programmierbare Completion (bash-completion)
Das Paket bash-completion erweitert die eingebaute Completion um kontextabhängige Vorschläge. Git schlägt dann Branch-Namen und Subkommandos vor, apt vervollständigt Paketnamen aus der Paketdatenbank, systemctl kennt alle registrierten Unit-Namen. Der Unterschied ist erheblich: Statt nur Dateipfade zu vervollständigen, versteht die Shell die Semantik des jeweiligen Befehls.
$ sudo apt install bash-completion
Auf Ubuntu und Debian-basierten Systemen ist das Paket oft bereits installiert und wird über /etc/bash.bashrc automatisch eingebunden. Prüfe es mit:
$ type _completion_loader
_completion_loader is a function
...
Gibt die Shell eine Funktion zurück, ist bash-completion aktiv. Falls nicht, reicht ein exec bash, um die Shell neu zu laden.
$HIS[Tab] und die Bash schlägt dir $HISTFILE, $HISTSIZE und $HISTCONTROL vor.Command History: Befehle wiederfinden und wiederverwenden
Jeder Befehl, den du in der Bash eingibst, landet in der History — standardmäßig in ~/.bash_history. Zwischen Sessions bleibt die History erhalten, sodass du Befehle von gestern oder letzter Woche wiederfinden kannst. Dafür gibt es mehrere Methoden, je nachdem wie genau du dich an den Befehl erinnerst.
Pfeiltasten und history-Befehl
Der direkteste Weg: Pfeiltaste hoch (↑) geht in der History zurück, Pfeiltaste runter (↓) vorwärts. Den vollständigen Verlauf mit Zeilennummern zeigt:
$ history
497 ls -la
498 cd /etc/network
499 cat interfaces
500 sudo systemctl restart networking
Jeder Eintrag hat eine Nummer. Mit !500 führst du exakt diesen Befehl erneut aus — ohne Bestätigung, er wird sofort ausgeführt. Mit !! wiederholst du den zuletzt eingegebenen Befehl. Das ist besonders praktisch, wenn du sudo vergessen hast:
$ apt update
E: Berechtigungen fehlen...
$ sudo !!
sudo apt update
Mit !string führst du den letzten Befehl aus, der mit diesem String begann:
$ !sys
sudo systemctl restart networking
Reverse-Search mit Ctrl+R
Die schnellste Suche in der History ist die inkrementelle Rückwärtssuche. Drücke Ctrl+R und tippe einen Teil des gesuchten Befehls — die Bash filtert in Echtzeit:
(reverse-i-search)`net': sudo systemctl restart networking
Die Bash zeigt sofort den letzten Treffer. Weiteres Ctrl+R springt zum nächstälteren Treffer. Mit Enter führst du den angezeigten Befehl aus. Mit Ctrl+G oder Ctrl+C brichst du die Suche ab, ohne etwas auszuführen. Wenn du den gefundenen Befehl erst noch bearbeiten willst, drücke stattdessen Esc oder die Pfeiltaste — dann landet er zur Bearbeitung in der Eingabezeile.
History konfigurieren
Zwei Umgebungsvariablen steuern, wie viele Einträge gespeichert werden:
HISTSIZE— Einträge im Speicher der laufenden Session (Standard: 500–1000 je nach Distribution)HISTFILESIZE— Zeilen in~/.bash_historyauf der Festplatte
Trage beide dauerhaft in ~/.bashrc ein:
# In ~/.bashrc
HISTSIZE=5000
HISTFILESIZE=10000
HISTCONTROL=ignoredups:erasedups
HISTTIMEFORMAT="%d.%m.%Y %H:%M "
HISTCONTROL=ignoredups verhindert, dass identische Befehle mehrfach hintereinander gespeichert werden. Meine .bashrc hat HISTSIZE=10000 — nach über 20 Jahren Bash-Nutzung greife ich ständig auf Befehle zurück, die Wochen alt sind. Wer weniger als 5000 einstellt, bereut es irgendwann. erasedups räumt zusätzlich alle älteren Duplikate aus der History raus. HISTTIMEFORMAT fügt jedem Eintrag einen Zeitstempel hinzu — hilfreich, wenn du nachvollziehen willst, wann ein Befehl ausgeführt wurde.
history -c leerst du die History der aktuellen Session vollständig. history -w schreibt den aktuellen Stand sofort in ~/.bash_history, ohne die Shell zu beenden.Aliases: Kurzbefehle für lange Kommandos
Aliases erlauben dir, eigene Kurznamen für häufig genutzte Befehle zu definieren. Technisch gesehen ersetzt die Bash beim Parsen den Alias-Namen durch die hinterlegte Zeichenkette — bevor der Befehl an das Betriebssystem übergeben wird. Ein Alias ist kein eigenständiges Programm, sondern eine reine Textersetzung in der Shell.
Alias erstellen und entfernen
$ alias ll='ls -lh'
$ ll
total 48K
drwxr-xr-x 2 gunter gunter 4,0K Apr 1 12:00 Dokumente
drwxr-xr-x 3 gunter gunter 4,0K Mär 28 09:15 Projekte
...
$ alias la='ls -la'
$ alias gs='git status'
$ unalias gs # Alias für diese Session entfernen
$ alias # Alle aktiven Aliases anzeigen
Ohne Argumente listet alias alle definierten Aliases mit ihren vollständigen Definitionen auf — nützlich, um nachzusehen, was hinter einem unbekannten Kürzel steckt.
Aliases dauerhaft speichern
In der Befehlszeile definierte Aliases gelten nur für die aktuelle Shell-Session. Nach dem Schließen des Terminals sind sie weg. Um sie dauerhaft zu machen, trägst du sie in ~/.bashrc ein — diese Datei wird bei jedem Start einer interaktiven Shell geladen:
# In ~/.bashrc
# Dateilisting
alias ll='ls -lh --color=auto'
alias la='ls -la --color=auto'
# Navigation
alias ..='cd ..'
alias ...='cd ../..'
# Git-Kürzel
alias gs='git status'
alias gc='git commit'
alias gp='git push'
alias gl='git log --oneline --graph'
# System
alias update='sudo apt update && sudo apt upgrade -y'
alias ports='ss -tulpn'
alias df='df -h'
Nach dem Speichern musst du die Datei neu einlesen, damit die Aliases sofort greifen:
$ source ~/.bashrc
# oder kurz:
$ . ~/.bashrc
Wann eine Funktion statt einem Alias?
Aliases haben eine Einschränkung: Sie können keine Argumente an beliebiger Position verarbeiten. Der Alias alias mkd='mkdir -p' funktioniert, weil das Argument ans Ende gehängt wird. Brauchst du aber mehr Kontrolle, zum Beispiel ein Argument in der Mitte oder eine Bedingung, nimm eine Shell-Funktion:
# Verzeichnis anlegen und direkt wechseln
mcd() {
mkdir -p "$1" && cd "$1"
}
# Aufruf:
$ mcd ~/projekte/neues-projekt
$ pwd
/home/gunter/projekte/neues-projekt
Funktionen kommen wie Aliases in ~/.bashrc und stehen nach dem nächsten source ~/.bashrc zur Verfügung. Mein persönlicher Favorit ist eine mkcd-Funktion — Verzeichnis anlegen und sofort hineinwechseln. Klingt trivial, spart aber bei der täglichen Arbeit erstaunlich viel Tipperei.
alias rm='rm -i' klingt sicher, weil es immer nachfragt — in Shellscripts die rm aufrufen, kann das aber zu Problemen führen, weil die Skriptausführung auf eine Tastatureingabe wartet, die nie kommt.Wildcards und Globbing
Globbing ist die Mustererkennung der Bash auf Basis von Dateinamen. Wenn du ls *.txt eingibst, expandiert die Bash das *.txt-Muster selbst — bevor ls gestartet wird. Das Programm sieht nie den Stern, sondern bekommt eine fertige Liste passender Dateien übergeben. Das unterscheidet Bash-Wildcards fundamental von regulären Ausdrücken, die von Programmen wie grep oder sed intern verarbeitet werden.
Die wichtigsten Muster
*— passt auf null oder mehr beliebige Zeichen (aber nicht auf/)?— passt auf genau ein beliebiges Zeichen[abc]— passt auf eines der aufgeführten Zeichen[a-z]— passt auf einen Zeichenbereich (abhängig vonLC_COLLATE)[!abc]— passt auf alle Zeichen außer den aufgeführten{a,b,c}— Brace Expansion: erzeugt mehrere unabhängige Varianten
# Alle .txt-Dateien im aktuellen Verzeichnis
$ ls *.txt
# Dateien mit genau drei Zeichen vor dem Punkt
$ ls ???.txt
# Nur Dateien die mit a, b oder c beginnen
$ ls [abc]*.txt
# Alle Dateien außer .log-Dateien kopieren
$ cp [!.]* /backup/
# Brace Expansion: drei Verzeichnisse auf einmal anlegen
$ mkdir -p projekt/{src,tests,docs}
# Brace Expansion mit Zahlen-Range
$ echo Datei{1..5}.txt
Datei1.txt Datei2.txt Datei3.txt Datei4.txt Datei5.txt
Brace Expansion ist besonders praktisch beim Umbenennen: mv config.yml{,.bak} benennt config.yml in config.yml.bak um — der zweite Teil bleibt leer, was die Bash zu mv config.yml config.yml.bak expandiert.
Globstar: Rekursiv durch Unterverzeichnisse
Mit shopt -s globstar aktivierst du das **-Muster, das rekursiv in Unterverzeichnisse abstieg:
$ shopt -s globstar
$ ls **/*.py # alle .py-Dateien im Baum
$ wc -l **/*.md # Zeilenzahl aller Markdown-Dateien
Damit globstar dauerhaft aktiv ist, trage shopt -s globstar in ~/.bashrc ein.
Umleitung und Pipes: Datenströme kontrollieren
Jedes Programm in Unix/Linux arbeitet standardmäßig mit drei Datenströmen: stdin (Standardeingabe, Dateideskriptor 0), stdout (Standardausgabe, Dateideskriptor 1) und stderr (Fehlerausgabe, Dateideskriptor 2). Die Bash erlaubt dir, diese Ströme frei umzuleiten — in Dateien, aus Dateien, oder direkt in andere Programme.
Ausgabe in Dateien schreiben
# stdout in Datei schreiben (überschreibt bestehende Datei)
$ ls -la > dateiliste.txt
# stdout an bestehende Datei anhängen (kein Überschreiben)
$ ls /etc >> dateiliste.txt
# Nur stderr in Datei umleiten
$ find / -name "geheim" 2> fehler.txt
# stdout und stderr zusammen in eine Datei umleiten
$ find / -name "geheim" &> alles.txt
# Ausgabe vollständig verwerfen
$ apt upgrade 2> /dev/null
/dev/null ist ein spezielles Gerät, das alle Eingaben stillschweigend verwirft — praktisch, um Fehlermeldungen zu unterdrücken, die dich nicht interessieren.
Pipes: Befehle zu Pipelines verketten
Der Pipe-Operator | verbindet den stdout eines Befehls direkt mit dem stdin des nächsten. Das ist das Kernkonzept der Unix-Philosophie: kleine Werkzeuge, die jeweils eine Sache gut können und sich kombinieren lassen.
# Alle laufenden Prozesse, gefiltert nach "python"
$ ps aux | grep python
# Die 10 größten Einträge im aktuellen Verzeichnis
$ du -sh * | sort -rh | head -10
# Zeilen einer Datei zählen
$ wc -l < /etc/passwd
# Ausgabe sortieren und Duplikate entfernen
$ cat zugriffslog.txt | sort | uniq -c | sort -rn | head -20
tee: Gleichzeitig anzeigen und speichern
tee ist ein T-Stück in der Pipe: es leitet stdout in eine Datei und gibt es gleichzeitig auf dem Terminal aus. Das ist nützlich, wenn du eine lang laufende Operation überwachen und das Protokoll gleichzeitig speichern willst:
$ sudo apt upgrade 2>&1 | tee upgrade-$(date +%F).txt
Das 2>&1 leitet stderr auf stdout um, bevor tee die Daten bekommt — so enthält die Protokolldatei auch Fehlermeldungen.
command < datei.txt liest du eine Datei als stdin ein — nützlich für Befehle, die normalerweise auf Tastatureingabe warten. sort < unsortiert.txt > sortiert.txt liest aus einer Datei und schreibt in eine andere.Tastenkürzel für die Befehlszeile
Die Bash nutzt standardmäßig die Readline-Bibliothek mit Emacs-Tastenbelegung. Diese Kürzel lassen dich die aktuelle Befehlszeile schnell bearbeiten — ohne Maus und ohne den Befehl neu tippen zu müssen. Besonders Ctrl+A und Ctrl+E sowie die Löschkürzel sparen täglich Zeit.
Cursor positionieren
Ctrl+A— Cursor an den Zeilenanfang springenCtrl+E— Cursor ans Zeilenende springenAlt+B— ein Wort nach linksAlt+F— ein Wort nach rechts
Text löschen
Ctrl+K— alles vom Cursor bis Zeilenende löschen (in Zwischenablage)Ctrl+U— alles vom Cursor bis Zeilenanfang löschen (in Zwischenablage)Ctrl+W— das Wort links vom Cursor löschenAlt+D— das Wort rechts vom Cursor löschenCtrl+Y— zuletzt gelöschten Text einfügen (Yank)
Sonstige Kürzel
Ctrl+L— Terminal leeren (wieclear, aber schneller)Ctrl+Z— laufenden Prozess suspendieren (in den Hintergrund schicken)Ctrl+C— laufenden Prozess abbrechen (SIGINT senden)Ctrl+D— Eingabe beenden (EOF) oder Shell schließen
# Langen Befehl tippen — dann Ctrl+A und Tippfehler am Anfang korrigieren
$ sudo systemctl restart networkng --verbose
# ↑ Tippfehler — Ctrl+A, dann Alt+F mehrfach vorwärts
# Prozess suspendieren und im Hintergrund weiterlaufen lassen
$ ping 8.8.8.8
^Z
[1]+ Gestoppt ping 8.8.8.8
$ bg
[1]+ ping 8.8.8.8 &
$ fg # wieder in den Vordergrund holen
bind -P zeigt die Bash alle aktiven Tastenbelegungen an. Mit set -o vi in ~/.bashrc wechselst du dauerhaft in den Vi-Modus — dann navigierst du mit h/l/w/b und bearbeitest mit c/d/y wie in vi.Weiterlesen
Tab-Completion, History, Aliases, Globbing, Pipes und Tastenkürzel — damit hast du das Handwerkszeug beisammen, das die tägliche Arbeit in der Bash spürbar schneller macht. Der nächste logische Schritt ist, wiederkehrende Aufgaben in Shellscripts zu packen. Wie du dabei vorgehst, zeigt der Script-Artikel. Falls du die Grundlagen der Shell noch festigen willst, hilft der Einstiegsartikel weiter.
Die Shell für Neulinge
Was ist die Bash, wie öffne ich ein Terminal, erste Schritte — der Einstieg von Null.
Grundlegende Kommandos
ls, cd, cp, mv, rm und Co. — die Werkzeuge, die du täglich brauchst.
Shellscripts schreiben
Befehle in Dateien sammeln, automatisieren und wiederverwenden — dein erster Script.