Ihre Shell speichert sie schon
Jeder Befehl, den Sie tippen, landet in der Shell-History, aber die Standardwerte sind klein, und die Datei wird erst beim Beenden der Shell geschrieben. Zwei Sitzungen gleichzeitig können sich gegenseitig Zeilen überschreiben. Für bash ergänzen Sie ~/.bashrc so:
HISTSIZE=100000
HISTFILESIZE=100000
HISTCONTROL=ignoreboth
HISTTIMEFORMAT='%F %T '
shopt -s histappend
PROMPT_COMMAND='history -a'
HISTSIZEundHISTFILESIZEhalten bis zu 100.000 Zeilen im Speicher und in der Datei.ignorebothlässt wiederholte Zeilen und Zeilen mit führendem Leerzeichen aus.HISTTIMEFORMATergänzthistoryum Datum und Uhrzeit.histappendundhistory -aschreiben jeden Befehl sofort in die Datei, sodass eine abgebrochene Verbindung nichts verliert. Hat IhrPROMPT_COMMANDschon einen Wert, setzen Siehistory -a;davor.
Für zsh, den Standard unter macOS, gehört das hier in ~/.zshrc:
HISTFILE=~/.zsh_history
HISTSIZE=100000
SAVEHIST=100000
setopt EXTENDED_HISTORY INC_APPEND_HISTORY HIST_IGNORE_SPACE HIST_IGNORE_DUPS
Machen Sie dasselbe auf den Servern, die Sie am meisten nutzen. Über SSH wird die History auf dem Server gespeichert, für den Benutzer, mit dem Sie angemeldet sind.
Einen Befehl wiederfinden
Drücken Sie Ctrl-R und tippen Sie einen beliebigen Teil des Befehls. Erneutes Ctrl-R zeigt ältere Treffer, Return führt aus, eine Pfeiltaste lässt Sie vorher bearbeiten. Für eine Liste:
history | grep journalctl
Mit den Zeitstempeln von oben zeigt die Liste, wann jeder Befehl lief:
1 2026-11-06 15:21:40 echo one
2 2026-11-06 15:21:40 diskfree /tmp
3 2026-11-06 15:21:40 uptime -p # @health
Die letzte Zeile zeigt einen nützlichen Trick. Ein Kommentar nach # bewirkt beim Ausführen nichts, bleibt aber in der History. Hängen Sie ein Tag wie # @health oder # @deploy an, dann findet Ctrl-R und @health jeden so markierten Befehl.
Aliase und Funktionen für wiederkehrende Befehle
Ein Befehl, den Sie jede Woche tippen, verdient einen kurzen Namen. Ein Alias ist fester Text. Eine Funktion kann Argumente annehmen:
alias logs='journalctl -u nginx --since "1 hour ago" --no-pager'
diskfree() { df -h "${1:-/}" | tail -n 1; }
diskfree allein prüft /, diskfree /var prüft diesen Ordner. Was ein Name tut, zeigt type logs. Aliase gelten nur in interaktiven Shells, ein Skript oder ssh server logs findet sie also nicht. Nutzen Sie dafür eine Funktion in einer eingebundenen Datei oder ein kleines Skript in ~/bin.
Ein gespeicherter Befehl pro Server in der SSH-Konfiguration
Für einen Befehl, den Sie immer auf einem Server ausführen, etwa einem Log folgen, kann die SSH-Konfiguration ihn bei der Anmeldung starten. Schreiben Sie das in ~/.ssh/config:
Host web1-logs
HostName web1
RemoteCommand tail -f /var/log/nginx/error.log
RequestTTY yes
ssh web1-logs öffnet dann direkt das Log. RequestTTY yes gibt dem Befehl ein Terminal, damit Ctrl-C funktioniert. Der Eintrag nimmt keinen zusätzlichen Befehl auf der Kommandozeile an: ssh web1-logs uptime scheitert mit Cannot execute command-line and remote command. Bei Bedarf überschreiben Sie ihn:
ssh -o RemoteCommand=none web1-logs uptime
Weitere Muster finden Sie in der Anleitung zur SSH-Config-Datei.
Alles in einer Datei, die Sie mitnehmen
Legen Sie Aliase und Funktionen in eine eigene Datei, laden Sie sie aus Ihrer Shell-Konfiguration und kopieren Sie sie auf die Server, die Sie nutzen:
mkdir -p ~/.config/shell
$EDITOR ~/.config/shell/commands.sh
echo '[ -f ~/.config/shell/commands.sh ] && . ~/.config/shell/commands.sh' >> ~/.bashrc
ssh web1 'mkdir -p ~/.config/shell' && scp ~/.config/shell/commands.sh web1:.config/shell/
Fügen Sie dieselbe echo-Zeile einmal in die ~/.bashrc des Servers ein. In einem Git-Repository behalten Sie den Verlauf der Datei und bringen sie leicht auf einen neuen Rechner. Um sie auf viele Server gleichzeitig zu verteilen, lesen Sie wie Sie einen Befehl auf mehreren Servern ausführen.
Was Sie nie speichern sollten
History-Dateien sind reiner Text. Ein auf der Kommandozeile getipptes Passwort, etwa mysql -pS3cret, bleibt dort für jeden lesbar, der die Datei lesen kann. Drei Wege, Geheimnisse herauszuhalten:
- Beginnen Sie die Zeile mit einem Leerzeichen. Mit
ignorebothin bash oderHIST_IGNORE_SPACEin zsh wird sie nicht gespeichert. - Schließen Sie Muster dauerhaft mit
HISTIGNOREin bash aus:
HISTIGNORE='*PASSWORD*:*TOKEN*'
- Entfernen Sie eine gerade getippte Zeile. Ab bash 5 löscht dies den Befehl davor:
history -d -2
Das korrigiert nur die History im Speicher. Ist die Zeile schon in der History-Datei, löschen Sie sie auch dort und ändern Sie das Passwort, denn es kann bereits anderswo hin kopiert worden sein. Besser noch: Lassen Sie das Programm nach dem Passwort fragen, mit mysql -p ohne etwas dahinter, oder lesen Sie Geheimnisse aus einer Datei mit strengen Rechten.
Fragen
Wo speichert bash meine Befehls-History?
In ~/.bash_history, geschrieben beim Beenden der Shell, außer Sie fügen history -a zu PROMPT_COMMAND hinzu. zsh nutzt die Datei in HISTFILE, oft ~/.zsh_history.
Enthält die History auf einem Server meine lokalen Befehle?
Nein. Jeder Rechner führt seine eigene History. Was Sie in einer SSH-Sitzung tippen, wird auf dem Server gespeichert, in der History des Benutzers, mit dem Sie angemeldet sind.
Wie verhindere ich, dass ein Befehl gespeichert wird?
Beginnen Sie ihn mit einem Leerzeichen, wenn HISTCONTROL in bash ignorespace enthält oder in zsh HIST_IGNORE_SPACE gesetzt ist. HISTIGNORE kann außerdem Muster wie *TOKEN* auslassen.
Was unterscheidet einen Alias von einer Funktion?
Ein Alias ersetzt das erste Wort eines Befehls durch festen Text. Eine Funktion ist ein kleines Programm, das Argumente annehmen kann, etwa einen Ordner oder einen Dienstnamen.
Quellen
- Bash-Handbuch: History-Funktionen
- Bash-Handbuch: Bash-Variablen (HISTCONTROL, HISTIGNORE)
- zsh-Handbuch: History-Optionen
- ssh_config(5), RemoteCommand