# zsh — die Z-Shell mit mächtigem Globbing und Completion

> zsh produktiv nutzen: Globbing, Glob-Qualifier, Arrays, Completion, setopt und Oh My Zsh – die Z-Shell jenseits von bash.

Source: https://www.jpkc.com/db/cheatsheets/shell-system/zsh/

<!-- PROSE:intro -->
zsh (Z-Shell) ist weitgehend kompatibel zu bash, legt aber kräftig nach: mächtige Tab-Completion, rekursives Globbing mit Glob-Qualifiern, 1-basierte Arrays und unzählige `setopt`-Schalter. Seit macOS Catalina ist zsh dort die Standard-Shell; auf Linux wechselst du mit `chsh -s $(which zsh)`. Frameworks wie Oh My Zsh oder Prezto liefern Themes, Plugins und sinnvolle Defaults gleich mit. Dieser Guide zeigt dir die Features, die zsh über bash hinaus wirklich produktiv machen.
<!-- PROSE:intro:end -->

## Globbing & Mustervergleich

`ls **/*.txt` — Rekursives Globbing. Findet Dateien in allen Unterverzeichnissen (standardmäßig aktiv).

```bash
ls **/*.json
```

`ls *(.)` — Glob-Qualifier: nur reguläre Dateien.

```bash
ls -la *(.) 
```

`ls *(/)` — Glob-Qualifier: nur Verzeichnisse.

```bash
ls -d *(/)
```

`ls *(@)` — Glob-Qualifier: nur symbolische Links.

```bash
ls -la *(@)
```

`ls *(om[1,5])` — Glob-Qualifier: die 5 zuletzt geänderten Dateien. o=Sortierung, m=mtime.

```bash
ls -la *(om[1,5])
```

`ls *(Lk+100)` — Glob-Qualifier: Dateien größer als 100 KB. L=Größe, k=KB, +=größer als.

```bash
ls -lh *(Lk+100)
```

`ls *(.mh-1)` — Glob-Qualifier: in der letzten Stunde geänderte Dateien. m=mtime, h=Stunden.

```bash
ls -la *(.mh-1)
```

`ls (#i)pattern` — Groß-/Kleinschreibung-unabhängiger Glob (benötigt EXTENDED_GLOB).

```bash
setopt EXTENDED_GLOB; ls (#i)readme*
```

`ls ^pattern` — Negations-Glob. Findet alles außer pattern (benötigt EXTENDED_GLOB).

```bash
setopt EXTENDED_GLOB; ls ^*.log
```

## Parameter-Expansion

`${(U)VAR}` — Wandelt einen String in Großbuchstaben um.

```bash
name='hello'; echo "${(U)name}"  # HELLO
```

`${(L)VAR}` — Wandelt einen String in Kleinbuchstaben um.

```bash
NAME='WORLD'; echo "${(L)NAME}"  # world
```

`${(C)VAR}` — Schreibt den ersten Buchstaben jedes Wortes groß.

```bash
str='hello world'; echo "${(C)str}"  # Hello World
```

`${(s:sep:)VAR}` — Zerlegt einen String anhand eines Trennzeichens in ein Array.

```bash
PATH_PARTS=(${(s/:/)PATH}); echo "${PATH_PARTS[1]}"
```

`${(j:sep:)ARRAY}` — Verbindet Array-Elemente mit einem Trennzeichen.

```bash
arr=(a b c); echo "${(j:,:)arr}"  # a,b,c
```

`${(t)VAR}` — Zeigt den Typ einer Variablen (scalar, array, integer usw.).

```bash
arr=(1 2 3); echo "${(t)arr}"  # array
```

`${(u)ARRAY}` — Entfernt doppelte Elemente aus einem Array (unique).

```bash
arr=(a b a c b); echo "${(u)arr}"  # a b c
```

`${(o)ARRAY} / ${(O)ARRAY}` — Sortiert ein Array aufsteigend / absteigend.

```bash
arr=(cherry apple banana); echo "${(o)arr}"
```

## Arrays & assoziative Arrays

`arr=(val1 val2 val3)` — Deklariert ein indiziertes Array. zsh-Arrays sind 1-basiert (nicht 0-basiert wie bash).

```bash
colors=(red green blue); echo "$colors[1]"  # red
```

`echo "$arr[1]"` — Greift auf das erste Element zu (1-basiert, anders als bash).

```bash
echo "$colors[2]"  # green
```

`echo "$arr[-1]"` — Greift über einen negativen Index auf das letzte Element zu.

```bash
echo "$colors[-1]"  # blue
```

`echo "$arr[2,4]"` — Array-Ausschnitt von Index 2 bis 4 (inklusive).

```bash
nums=(10 20 30 40 50); echo "$nums[2,4]"  # 20 30 40
```

`typeset -A map` — Deklariert ein assoziatives Array.

```bash
typeset -A ports; ports=(http 80 https 443)
```

`echo "${(k)map}"` — Liefert alle Schlüssel eines assoziativen Arrays.

```bash
echo "${(k)ports}"  # http https
```

`echo "${(kv)map}"` — Liefert alle Schlüssel-Wert-Paare eines assoziativen Arrays.

```bash
echo "${(kv)ports}"  # http 80 https 443
```

## History & Navigation

`Ctrl+R` — Inkrementelle Rückwärtssuche in der History.

```bash
Ctrl+R, then type to search
```

`!!` — Wiederholt den letzten Befehl.

```bash
sudo !!
```

`!$` — Letztes Argument des vorherigen Befehls.

```bash
mkdir mydir; cd !$
```

`!*` — Alle Argumente des vorherigen Befehls.

```bash
echo foo bar baz; echo !*
```

`!<string>` — Führt den letzten Befehl aus, der mit string beginnt.

```bash
!docker
```

`fc` — Öffnet den letzten Befehl im $EDITOR zum Bearbeiten und erneuten Ausführen.

```bash
fc
```

`history 1` — Zeigt die vollständige Befehls-History (zsh nummeriert ab 1).

```bash
history 1 | grep ssh
```

`setopt SHARE_HISTORY` — Teilt die History zwischen allen laufenden zsh-Sitzungen.

```bash
setopt SHARE_HISTORY
```

## Tab-Vervollständigung

`Tab` — Vervollständigt Befehl, Pfad oder Argument. Zeigt bei Mehrdeutigkeit ein Menü.

```bash
git che<Tab>  # completes to git checkout
```

`Tab Tab` — Blättert durch die Optionen im Vervollständigungsmenü.

```bash
cd /u<Tab><Tab>  # cycles through /usr, /Users, etc.
```

`compinit` — Initialisiert das Vervollständigungssystem. Üblicherweise in der .zshrc.

```bash
autoload -Uz compinit && compinit
```

`zstyle ':completion:*' menu select` — Aktiviert die interaktive Menüauswahl für Vervollständigungen.

```bash
zstyle ':completion:*' menu select
```

`zstyle ':completion:*' matcher-list 'm:{a-z}={A-Z}'` — Aktiviert Groß-/Kleinschreibung-unabhängige Tab-Vervollständigung.

```bash
zstyle ':completion:*' matcher-list 'm:{a-z}={A-Z}'
```

## Shell-Optionen (setopt)

`setopt AUTO_CD` — Verzeichnisnamen eingeben, um hineinzuwechseln (ohne cd).

```bash
setopt AUTO_CD; /tmp  # same as cd /tmp
```

`setopt CORRECT` — Aktiviert die Rechtschreibkorrektur für Befehle.

```bash
setopt CORRECT; gti status  # suggests: git?
```

`setopt CORRECT_ALL` — Aktiviert die Rechtschreibkorrektur für Befehle und Argumente.

```bash
setopt CORRECT_ALL
```

`setopt NO_CASE_GLOB` — Macht Globbing Groß-/Kleinschreibung-unabhängig.

```bash
setopt NO_CASE_GLOB; ls *.TXT  # matches .txt too
```

`setopt EXTENDED_GLOB` — Aktiviert erweiterte Globbing-Operatoren (^, ~, #).

```bash
setopt EXTENDED_GLOB; ls ^*.log
```

`setopt GLOB_DOTS` — Bezieht versteckte Dateien ohne expliziten Punkt in Glob-Treffer ein.

```bash
setopt GLOB_DOTS; ls *
```

`setopt HIST_IGNORE_DUPS` — Speichert keine doppelten Befehle in der History.

```bash
setopt HIST_IGNORE_DUPS
```

`setopt HIST_IGNORE_SPACE` — Speichert keine Befehle, die mit einem Leerzeichen beginnen.

```bash
setopt HIST_IGNORE_SPACE; echo 'secret'
```

`setopt APPEND_HISTORY` — Hängt an die History-Datei an, statt sie zu überschreiben.

```bash
setopt APPEND_HISTORY
```

`unsetopt <option>` — Deaktiviert eine Shell-Option.

```bash
unsetopt CORRECT
```

## Prompt anpassen

`PROMPT='%n@%m %~ %# '` — Setzt den linken Prompt. %n=Benutzer, %m=Host, %~=Verzeichnis, %#=Rechte.

```bash
PROMPT='%n@%m %~ %# '
```

`RPROMPT='%T'` — Setzt den rechten Prompt (zsh-exklusiv). %T=Uhrzeit.

```bash
RPROMPT='%T'
```

`%F{color}text%f` — Färbt Text im Prompt. %F beginnt die Farbe, %f setzt sie zurück.

```bash
PROMPT='%F{green}%n%f@%F{blue}%m%f %~ %# '
```

`%B text %b` — Fett gedruckter Text im Prompt.

```bash
PROMPT='%B%n%b@%m %~ %# '
```

`autoload -Uz promptinit; promptinit` — Lädt das System der eingebauten Prompt-Themes.

```bash
autoload -Uz promptinit; promptinit; prompt -l
```

## Verzeichnis-Stack

`pushd <dir>` — Wechselt das Verzeichnis und legt es auf dem Stack ab.

```bash
pushd /var/log
```

`popd` — Holt ein Verzeichnis vom Stack und wechselt dorthin.

```bash
popd
```

`dirs -v` — Zeigt den Verzeichnis-Stack mit Index-Nummern.

```bash
dirs -v
```

`cd -<n>` — Wechselt zum Verzeichnis an Stack-Position n (zsh-Feature).

```bash
cd -2
```

`setopt AUTO_PUSHD` — Legt bei jedem cd automatisch Verzeichnisse auf dem Stack ab.

```bash
setopt AUTO_PUSHD; cd /tmp; cd /var; dirs -v
```

`setopt PUSHD_IGNORE_DUPS` — Legt keine doppelten Verzeichnisse auf dem Stack ab.

```bash
setopt PUSHD_IGNORE_DUPS
```

## Aliase & Funktionen

`alias name='command'` — Erstellt einen einfachen Alias.

```bash
alias ll='ls -la'
```

`alias -g NAME='text'` — Erstellt einen globalen Alias. Wird überall in der Befehlszeile expandiert.

```bash
alias -g G='| grep'; ls G pattern
```

`alias -s ext=command` — Suffix-Alias. Verknüpft eine Dateiendung mit einem Befehl.

```bash
alias -s json=code; ./data.json  # opens in VS Code
```

`which <command>` — Zeigt, wo ein Befehl definiert ist (Alias, Funktion oder Binary).

```bash
which ls
```

`functions <name>` — Zeigt die Definition einer Funktion.

```bash
functions greet
```

## Oh My Zsh

`plugins=(git docker npm)` — Aktiviert Plugins in der .zshrc. Leerzeichen-getrennte Liste.

```bash
plugins=(git docker npm node composer)
```

`ZSH_THEME='robbyrussell'` — Setzt das Prompt-Theme in der .zshrc.

```bash
ZSH_THEME='agnoster'
```

`omz update` — Aktualisiert Oh My Zsh auf die neueste Version.

```bash
omz update
```

`omz plugin list` — Listet alle verfügbaren Oh-My-Zsh-Plugins auf.

```bash
omz plugin list
```

`omz theme list` — Listet alle verfügbaren Oh-My-Zsh-Themes auf.

```bash
omz theme list
```

## Konfigurationsdateien

`~/.zshenv` — Wird immer geladen (Login, interaktiv, Skripte). Für PATH und Exporte.

```bash
export PATH="$HOME/bin:$PATH"
```

`~/.zprofile` — Wird nur für Login-Shells geladen. Ähnlich der .bash_profile.

```bash
eval "$(brew shellenv)"
```

`~/.zshrc` — Wird für interaktive Shells geladen. Die zentrale Konfigurationsdatei.

```bash
source ~/.zshrc  # reload config
```

`~/.zlogin` — Wird nach der .zshrc für Login-Shells geladen.

```bash
# login message
```

`~/.zlogout` — Wird beim Beenden einer Login-Shell geladen.

```bash
# cleanup tasks
```

`source ~/.zshrc` — Lädt die zsh-Konfiguration neu, ohne die Shell neu zu starten.

```bash
source ~/.zshrc
```

## Häufige Muster

`zmv 'pattern' 'replacement'` — Benennt Dateien stapelweise per Muster um (mit autoload zmv laden).

```bash
autoload zmv; zmv '(*).txt' '$1.md'
```

`ls -la **/*.log(.mw-1)` — Findet rekursiv alle Log-Dateien, die in der letzten Woche geändert wurden.

```bash
ls -la **/*.log(.mw-1)
```

`print -l **/*.js` — Listet Treffer eine Datei pro Zeile (übersichtlicher als ls).

```bash
print -l **/*.js
```

`echo ${(F)array}` — Gibt Array-Elemente eine pro Zeile aus (F = mit Zeilenumbruch verbinden).

```bash
arr=(one two three); echo "${(F)arr}"
```

`for f in **/*(.Lm+10); do echo "$f"; done` — Findet rekursiv Dateien größer als 10 MB.

```bash
for f in **/*(.Lm+10); do echo "$f"; done
```

`take <dir>` — Erstellt ein Verzeichnis und wechselt hinein (Oh-My-Zsh-Funktion).

```bash
take new-project
```

<!-- PROSE:outro -->
## Fazit

zsh fühlt sich für bash-Umsteiger sofort vertraut an, belohnt dich aber mit deutlich mehr Komfort: rekursives Globbing samt Qualifiern, flexible Parameter-Expansion, ein durchdachtes Completion-System und Frameworks wie Oh My Zsh ersparen dir viel Tipparbeit. Achte auf die kleinen, aber wichtigen Unterschiede zu bash – allen voran die 1-basierte Array-Indizierung und das von `setopt` gesteuerte Verhalten beim Globbing und in der History. Lege deine Anpassungen in `~/.zshrc` ab, halte Skripte mit `#!/usr/bin/env zsh` portabel und teste verändertes Glob- oder Korrektur-Verhalten lieber einmal mehr, bevor du es in produktive Skripte übernimmst.

## Weiterführende Links

- [ubuntuusers-Wiki: Zsh](https://wiki.ubuntuusers.de/Zsh/) – deutschsprachige Einführung in Installation und Konfiguration
- [Oh My Zsh](https://ohmyz.sh/) – beliebtes Framework mit Themes, Plugins und sinnvollen Defaults
- [zsh-Handbuch](https://zsh.sourceforge.io/Doc/) – offizielle Referenz zu Optionen, Expansions und Glob-Qualifiern
<!-- PROSE:outro:end -->

## Verwandte Kommandos

- [bash](https://www.jpkc.com/db/cheatsheets/shell-system/bash/) – die GNU-Bourne-Again-Shell, Standard auf den meisten Linux-Distributionen
- [fish](https://www.jpkc.com/db/cheatsheets/shell-system/fish/) – nutzerfreundliche Shell mit Autosuggestions ab Werk
- [env](https://www.jpkc.com/db/cheatsheets/shell-system/env/) – Umgebungsvariablen anzeigen und Programme in angepasster Umgebung starten

