Die Zsh ist einfach cool. Schon jahrelang beherrscht sie Funktionen, die erst im Laufe der Zeit bei der Bash eingebaut wurden (z. B. gute Tabcompletion). Daher bin ich schon Mitte der 2000er zur Zsh gewechselt und bisher hat mich keine andere Shell zum Wechseln überzeugen können.
Neben der interaktiven Arbeit mit der Zsh ist mein größter Schatz meine ~/.zshrc (und ~/.zshenv und ~/.zhistfile), in der viele Einstellungen zur Erleichterung der täglichen Arbeit liegen.
Alias
Mit dem Befehl alias
kann man sich Abkürzungen für Befehle definieren. Oft
lässt sich das Verhalten von Befehlen mit Kommandozeilenoptionen verändern. Hier
ein paar einfache Beispiele:
alias ffmpeg='ffmpeg -hide_banner'
alias agu='apt update'
alias search='apt-cache search
alias supernice='ionice -c 3 chrt --batch 0 choom -n 1000 -- nice'
Aliase müssen aber keine reinen Befehle seien, sondern auch nur Teile des Anfangs einer Befehlszeile. Somit kann man Variablendefinitionen für diesen einen Befehl voranstellen.
Die Aliase können auch geschachtelt werden und auf andere Aliase zurückgreifen.
alias c='RUST_BACKTRACE=short CARGO_TERM_COLOR=always cargo'
alias LCC='LC_ALL=C.UTF-8'
alias strace='LCC strace -fvttTy'
alias make="supernice make -j$(nproc --ignore 1)"
Außerdem kann man bei der Definition der Aliase auch Shellcode für eine Differenzierung verwenden. So nutze ich die selbe Datei für Root und meinen Benutzer bzw. unterscheide ich an einigen Stellen je nach Hostname oder anderen Kriterien:
if $USERNAME == root
then
alias rm='rm -i --one-file-system'
else
alias rm='rm --one-file-system'
fi
case $OSTYPE in
Darwin) alias ls='ls -AGhx';;
SunOS|OSF1) alias ls='ls -Ahx';;
*) alias ls='ls --color=auto -Ahx';;
esac
if $osrelease == debian.8
then
alias j='SYSTEMD_LESS=$LESS LCC journalctl'
else
alias j='SYSTEMD_LESS=$LESS LCC journalctl --no-hostname'
fi
Eine Besonderheit der Zsh sind globale Aliase. Diese werden nicht nur am Anfang, sondern überall in der Eingabe ersetzt. Daher sollte man damit vorsichtig umgehen, aber man kann sich so schöne Helferlein schaffen, die sehr viel Tipparbeit ersparen.
alias -g 1DN='>/dev/null'
alias -g 2DN='2>/dev/null'
alias -g DN='1DN 2DN'
alias -g CG='2>&1 |noglob grep --color=always'
alias -g G='2>&1 |noglob grep'
alias -g L='2>&1 |less'
Somit lassen sich Ausgaben mit cat datei DN
leicht unterdrücken oder mit cat
datei CG begriff L
filtern.
Zurückstellen und aktuelle Hilfe
Mit Alt-q
kann man jederzeit die aktuelle Eingabe zurückstellen, einen neuen
Befehl eingeben und ausführen und bekommt danach die zurückstellte Eingabe
wieder. Dieser Mechanismus wurde mit Alt-h
dazu kombiniert, dass für den
aktuellen Befehl die Hilfe (Manualpage) aufgerufen wird. Bei einigen Befehlen
sind jedoch die Manualpages nicht hilfreich, aber man kann sich selbst
Funktionen run-help-BEFEHL
definieren, die für BEFEHL
die passende Hilfe
anzeigen:
run-help-adb()
{
adb help 2>&1 |less
}
run-help-openssl()
{
# die Unterprogramme sind in eigenen Manualpages beschrieben; z.B. x509(1)
man ${1:-openssl}
}
run-help-perf()
{
# die Unterprogramme sind in eigenen Manualpages beschrieben; z.B. perf-stat(1)
man perf${1:+-$1}
}
Bearbeitung des letzten Befehls
Manchmal führt man auch Befehlsfolgen aus, die sich im Grunde nur an einer
Stelle unterscheiden. Bei der Zsh wurde die !
‐Auswertung noch erweitert. Mit
!!
lässt sich immer der letzte Befehl wiederholen und mit ^1^2
kann man das
erste 1
durch 2
ersetzen. Wenn dies an mehreren Stellen passieren soll, muss
man ^1^2^:G
eingeben.
Um die aktuelle Eingabe zu bearbeiten, verwende ich die Funktionen
replace-string
und replace-pattern
. Diese habe ich an keine
Tastenkombination gebunden, sondern nutze den Funktionsaufruf mit Alt-x
. In
der Konfigurationsdatei müssen die Funktionen mit folgenden Befehlen bekannt
gemacht werden:
autoload replace-string
zle -N replace-string
zle -N replace-pattern replace-string
Nächster Befehl anhand der Historie
Neben der Konfiguration in der ~/.zshrc zählt die Historie der Eingaben zu den
größten Schätzen. Ich habe diese auch mit der Einstellung SAVEHIST=5000
auf
5000 Einträge vergrößert, sodass ich auf einen reichhaltigen Fundus zugreifen
kann. Mit den Einstellungen setopt append_history extended_history
hist_expire_dups_first hist_find_no_dups hist_ignore_all_dups hist_save_no_dups
lässt sich auch beim Speichern die Historie bereinigen und mit
Zusatzinformationen über den Aufrufzeitpunkt (extended_history
) ergänzen.
Auf diese Weise kann ich mit Strg-r
in der Historie einen Befehl suchen und
ausführen. Auf diese Weise habe ich kleine Skripte abgelegt, die ich recht
häufig nutze. Mit Strg-o
kann man automatisch den nächsten Befehl aus der
Historie zur Vorlage bringen.
Teile aus den vorherigen Eingaben holen
Oft nutzt man in neuen Eingaben Teile, insbesondere den letzten, der vorherigen
Eingabe. Mit Alt-.
kann man sehr schnell darauf das letzte Argument zugreifen.
Durch wiederholtes Drücken kann man durch auf die vorherigen Eingaben zugreifen
und mit einem Prefix-Argument (Alt-1
… Alt-9
) eine andere Position als die
letzte Wählen.
Alternativ kann man auch dafür die !
-Ausdrücke verwenden: !-3:4*
sind alle
Argumente ab dem vierten von der drittvorletzten Eingabe. Oder einfach !$
für
das letzte Argument der letzten Eingabe. Mit !*
erhält man die letzte Eingabe
ohne das erste Wort, womit sich leicht less …
gefolgt von rm !*
eingeben
lässt.
Ressourcenverbrauch von Befehlen
Ähnlich wie die Slow-Queries bei Datenbanken kann man sich auch von der Zsh Informationen zu Befehlen anzeigen lassen, die viel CPU-Zeit verbraucht haben. Wenn ein Befehl länger als zwei Sekunden läuft wird danach eine Auswertung des Ressourcenverbrauchs angezeigt: System- und Prozessanteil, RAM-Verbrauch, Page-Faults, Context-Switches.
REPORTTIME=2
TIMEFMT='%J usr %U sys %S tot %*E %MMB pf %F %R cs %w %c'