Die moderne und mit zahlreichen nützlichen Features ausgestattetete Z-Shell bietet Kommandozeilen-Arbeitern eine attraktive Alternative zur klassischen Bash. Wir zeigen die Möglichkeiten und helfen beim Einstieg.
Eine Shell ist ein Programm, welches Text einliest und diesen Text als Kommando interpretiert und ausführt – so definiert trocken das Lexikon Wikipedia. Heute erledigt eine Shell jedoch in der Regel weitaus mehr, als nur Kommandos zu interpretieren. Eine moderne Shell kann jede Menge Kommandos und Parameter vervollständigen, unterstützt eine eigene Scriptsprache und besitzt Funktionen, die dem Anwender rundum das Leben erleichtern. Die meisten Distributionen setzen in Sachen Standard-Shell auf die Bash. Wer allerdings viel mit der Kommandozeile arbeitet, vermisst wahrscheinlich oftmals einige Möglichkeiten, die der Bash schlicht fehlen. Hier springt die Z-Shell in die Lücke.
Entwickelt wurde die Z-Shell (kurz Zsh) 1989 von Paul Falstad. Falstad wollte eine neue Shell schreiben, welche die Vorteile und Verbesserungen der Shells Bash, Csh und Ksh kombinieren und darüber hinaus noch weitere, neue Features implementieren sollte. Inzwischen wird die Entwicklung von den Mitgliedern der Mailingliste zsh-workers@sunsite.dk fortgeführt und von Peter Stephenson koordiniert.
Installation
Viele Distributionen bringen die Zsh schon mit, bei den anderen können Sie sie über den Paketmanager nachinstallieren. Entsprechende Pakete im RPM-Format finden sich beispielsweise bei RPMSeek [1] und lassen sich mit dem Befehl rpm -i Paket.rpm installieren.
Alternativ können Sie die Z-Shell auch aus den aktuellen Quellen selbst übersetzen. Diese finden Sie auf einem der vielen Mirrors des Zsh-Projekts und auf der Heft-CD dieser Ausgabe. Besondere Abhängigkeiten werden nicht benötigt. Um die Zsh zu kompilieren und (als root) zu installiert, nutzen Sie den bekannten Dreisprung:
./configure make su -c "make install"
Wechsel zur Zsh
Möchten Sie lediglich die die Beispiele dieses Artikels nachvollziehen, dann starten Sie die Zsh dazu durch Eingabe des Befehls exec zsh auf der Kommandozeile. Wollen Sie die Zsh dagegen als Login-Shell verwenden, dann gilt es zunächst zu prüfen, ob das Syste ihre Verwendung zu diesem Zweck auch erlaubt. Dazu muss sie in der Datei /etc/shells mit vollem Pfad aufgeführt sein. Findet sich dort kein entsprechender Eintrag, so stellen Sie zuerst einmal mit dem Befehl which zsh den Pfad zur Zsh fest und tragen ihn (als root) in /etc/shells nach (Listing 1).
Listing 1
Prüfen von /etc/shells
# grep zsh /etc/shells # where zsh /usr/bin/zsh # echo "/usr/bin/zsh" >> /etc/shells
Nachdem Sie diesen Eintrag vorgenommen haben, tauschen Sie Ihre Login-Shell gegen die Zsh aus. Das erledigen Sie mit dem Befehl chsh -c /Pfad/Zur/zsh Benutzername. Eventuell müssen Sie chsh aufgrund von Restriktionen der Distribution möglicherweise als root aufrufen – obwohl der Befehl eigentlich Benutzern ermöglichen soll, ihre Login-Shell selbst zu wechseln.
Beim Ändern der Shell sollten Sie als derjenige Benutzer, dessen Shell geändert werden soll, stets eingeloggt bleiben und auf einer anderen Konsole prüfen, ob der Wechsel erfolgreich verlaufen ist. Haben Sie sich beispielsweise beim Pfad vertippt, ist ein Einloggen des Benutzers ohne ein erneutes chsh oder Editieren der Datei /etc/passwd nicht mehr möglich.
Alternativ können Sie die Zsh mittels des Parameters -l oder --login auch explizit als Login-Shell starten.
Konfigurationsdateien
Zur Konfiguration der Zsh dienen dem Systemverwalter die fünf Konfigurationsdateien /etc/zshenv, /etc/zprofile, /etc/zshrc, /etc/zlogin und /etc/zlogout (Debian lagert diese Files in /etc/zsh). Diese Dateien kann zusätzlich auch jeder Benutzer für sich in seinem Home-Verzeichnis anlegen. Über die Umgebungsvariable $ZDOTDIR geben Sie bei Bedarf als Lagerort ein anderes Verzeichnis an als $HOME – etwa ZDOTDIR=$HOME/.zsh.
Gemäß Konvention beginnen die Dateinamen der benutzerspezifischen Konfigurationsdateien mit einem Punkt, heissen also .zshenv, .zprofile und so fort. Zu Gunsten der besseren Lesbarkeit lassen wir im folgenden die Pfadangabe der Konfigurationsdateien sowie den gegebenenfalls führenden Punkt weg..
Beim Start liest die Zsh zunächst die vom Administrator angelegten Dateien ein (aus /etc bzw /etc/zsh), danach jene des Benutzers. So kann jeder Anwender die vom Systemverwalter getroffenen Voreinstellungen über seine eigenen Konfigurationsdateien modifizieren.
Als erste Datei wertet die Z-Shell zshenv aus. In ihr finden sich wichtige Umgebungsvariablen, wie zum Beispiel Pfadangaben (PATH, CDPATH, MANPATH) oder Settings wie DISPLAY, EDITOR, PAGER und PRINTER.
Eine als Login-Shell gestartete Zsh liest nach der zshenv auch die Dateien zprofile und zlogin. Jede Z-Shell (ob Login oder nicht) wertet anschließend die Datei zshrc aus. Vor der Beendigung liest eine Zsh-Login-Shell zudem noch zlogout.
Sie müssen die Konfigurationsdateien nicht zwangsläufig modifizieren: Wie fast alle Shells läuft die Zsh auch ohne vorherige Konfiguration tadellos. Allerdings bieten die Konfigurationsdateien zahlreiche Möglichkeiten, die Shell gezielt an ihre Wünsche anzupassen. Welche Datei dabei wozu dient, fasst Tabelle 1 kurz zusammen.
Tabelle 1: Zsh-Konfigurationsdateien
| Datei | Inhalt |
|---|---|
zshenv |
Umgebungsvariablen |
zlogin |
(nur Login-Shell) Befehle, die Zsh beim Start ausführt |
zprofile |
(nur Login-Shell) Befehle, die das Benutzerprofil betreffen. Zsh führt diese beim Login vor der zshrc aus |
zshrc |
Befehle, die Zsh bei jedem Shell-Start ausführt |
zlogout |
(nur Login-Shell) Befehle, die Zsh beim Beenden ausführt |
Geschichtliches
Alle Befehle, die Sie eingeben, kann sich Zsh in einer Liste merken – der so genannten History. Um diese History zu aktivieren, müssen Sie die drei Umgebungsvariablen HISTSIZE, HISTFILE und SAVEHIST setzen. Dabei bestimmt HISTSIZE die maximale Anzahl der Einträge, die Zsh in der History vorhält. HISTFILE bezeichnet diejenige Datei, in der Zsh die History vor dem Beenden speichert. SAVEHIST schließlich definiert die Anzahl der Zeilen, die dann in das $HISTFILE geschrieben werden sollen. Eine typische Konfiguration sieht etwa folgendermaßen aus:
Listing 2: Die History HISTSIZE=500 HISTFILE=~/.zsh_history SAVEHIST=100
Die Z-Shell merkt sich hier zur Laufzeit die letzten 500 Befehlszeilen, speichert davon aber nur die letzten 100 in der angegebenen Datei. Beim nächsten Start können Sie die gespeicherten Zeilen wieder über die History abrufen.
Darüber hinaus durchsuchen Sie mit [CTRL]+[R] die History nach Befehlen. Durch mehrmaliges Drücken dieser Tastenkombination gehen Sie die gefundenen Eingaben der Reihe nach durch. Ein “^” steht für den Zeilenanfang und kann dem Suchbegriff vorangestellt werden. Hat Zsh den gesuchten Befehl gefunden, führen Sie ihn bei Bedarf mit [Enter] erneut aus. Mit [CTRL]+[4] brechen Sie dagegen die Suche wieder ab.
Der Prompt
Ein übersichtlicher Prompt erleichtert die effektive Arbeit auf der Shell deutlich, zudem beeinflusst er auch wesentlich deren Erscheinungsbild. Den Prompt der Zsh definieren Sie durch andere Kürzel als denjenigen der Bash. Daher können Sie die entsprechende Zeile aus einer vorhandenen Bash-Konfigurationsdatei nicht einfach übernehmen.
Wie der Prompt aussieht, bestimmen Sie mithilfe der Umgebungsvariable PROMPT. Sie enthält Platzhalter für Systeminformationen und Pfade. Die Shell interpretiert den Inhalt dieser Variablen und zeigt den entsprechenden Prompt an. Da es sich bei PROMPT um eine Umgebungsvariable handelt, die bei jedem Start der Shell gesetzt werden sollte, empfiehlt sich ein Eintrag in der Datei zshenv. Welche Platzhalter es gibt und wie der Prompt genau funktioniert, finden Sie im Manual zu zshmisc unter dem Punkt “Prompt Expansion”:
man zshmisc | less +/^PROMPT
Im folgenden wollen wir einen praktischen Prompt entwickeln, der zwei interessante Eigenschaften der Zsh nutzen soll. Zum einen soll sich die Angabe des aktuellen Verzeichnisses auf die letzten Überverzeichnisse begrenzen, um die Länge des Prompts nicht ausufern zu lassen. Zum anderen unterstützt die Zsh sogenannte Bedingungen (“Conditions”), mit deren Hilfe sie auf bestimmte Zustände mit Ereignissen reagieren kann. Das wollen wir dazu nutzen, den Rückgabewert des letzten Befehls auszuwerten, um sofort zu erkennen, ob ein Fehler aufgetreten ist. Das erweist sich vor allem bei der Ausführung von Befehlen als praktisch, die viele Meldungen auf der Standardausgabe produzieren – beispielsweise make.
Erste Prompt-Schritte
Am Beginn steht ein einfach Standard-Prompt, der dem Schema Benutzername@Host folgt:
PROMPT=%n@%m
Hier steht der Ausdruck “%m” für den Namen des Rechners (den Hostname), das “%n” für den Namen des Benutzers. Nun fügen Sie noch ein Trennzeichen zwischen Prompt und Eingabebeginn hinzu: “%#” gibt ein Doppelkreuz aus, wenn root die Shell benutzt, bei normalen Benutzern erscheint stattdessen ein Prozent-Zeichen:
PROMPT='%n@%m%#'
Nun fügen Sie mittels “%~” die Ausgabe des aktuellen Verzeichnisses hinzu, das Sie mit einem Doppelpunkt vom Hostnamen abtrennen. Der Optik halber platzieren Sie das ganze noch in eckigen Klammern und setzen das Abschluss-Zeichen durch eine Leerstelle ab:
PROMPT=$'[%n@%m:%~] %#'
Liegt das aktuelle Verzeichnis mehr als 4 Ebenen vom Wurzelverzeichnis entfernt, fällt der Prompt recht unübersichtlich aus und verlängert sich vor allem immer weiter nach rechts. Um das zu verhindern, zeigen Sie am besten ab der vierten Verzeichnisebene nur noch den Namen des aktuellen Verzeichnisses an. Diesen Vorgang nennt man Truncating. Erlässt sich mit der Zsh über Conditions realisieren. Diese definieren Sie nach dem Schema %(Bedingung,Aktion wenn wahr,Aktion wenn falsch).
Als Trennzeichen zwischen Bedingung und Aktionen müssen Sie nicht unbedigt das Komma verwenden. Zsh interpretiert einfach das erste Zeichen nach der Bedingung als Trenner. Dieses sollte dann allerdings im Rest der Condition tatsächlich ausschließlich als Trennzeichen vorkommen.
Als Bedingung verwenden Sie “4c”. “c” bezeichnet hier die Elemente des aktuellen Pfades (/ zählt dabei nicht als Element); mit der “4” prüfen Sie, ob der Pfad vier oder mehr Elemente enthält. Als Aktion geben Sie entweder mit “%~” den kompletten Pfad aus oder mit “%1~” nur das erste Element des Pfades, also das aktuelle Verzeichnis. Als Kennzeichnung für das Truncating fügen Sie dem gekappten Pfad noch ein “./” hinzu:
PROMPT=$'[%n@%m:%(4c,./%1~,%~)] ? %# '
Um den Rückgabewert des letzten Befehls auszuwerten benutzen Sie ebenfalls eine einfache Condition:
PROMPT=$'[%n@%m:%(4c,./%1~,%~)] ? %(?,:%),:%() %# '
Die Bedingung “?” ist erfüllt, wenn der Exit-Status des letzten Befehls “0” war, also kein Fehler aufgetreten ist. Dann hängt Zsh ein Smiley an den Prompt an. Bei einem Rückgabewert ungleich Null dagegen hängen die Mundwinkel unglücklich nach unten.
Zusätzlich können Sie im Prompt auch Farben für eine eingängigere Darstellung nutzen. Wollen Sie etwa die Klammern und den Klammeraffen in Grün eingefärben sowie das Smiley je nach Art des Rückgabewertes Rot oder Grün dargestellen, lässt sich das über sogenannte Escape-Sequenzen erreichen. Eine Escape-Sequenz ist eine Folge von Steuerzeichen, welche mit einem ESC beginnt.
Im Terminal lassen sich solche Sequenzen zur Steuerung des Cursors oder eben auch zur Änderung der aktuell verwendeten Farbe einsetzen. In der Zsh müssen Sie sie mit “${}” einklammern. Um zum Beispiel den Klammeraffen im Prompt grün einzufärben, geben Sie folgende Zeichenkette an:
%{e\[0;32m%}@%{e\[0m%}
Die zweite, abschliessende Escape-Sequenz (“e\[0m%”) stellt alle nachfolgenden Zeichen wieder normal dar. Für den optisch aufgewerteten Prompt können sich auch Fettung als Formatierungsmöglichkeit nutzen: Mit einem einleitenden “%B” und einem abschliessenden “%b” hebt die Zsh Textteile fett hervor:
PROMPT=$'%{\e[0;32m%}%B[%b%{\e[0?
m%}%n%{\e[0;32m%}@%{\e[0m%}%m%{\?
e[0;32m%}%B:%b%{\e[0m%}%(4c,./%1?
~,%~)%{\e[0;32m%}%B]%b%{\e[0m%} ?
%(?,%{\e[0;32m%}:%)%{\e[0m%},%{\?
e[0;31m%}:(%{\e[0m%}) %# '
Fügen Sie alle besprochenen Escape-Sequenzen entsprechend in Ihren Prompt ein, sieht das Ergebnis so aus, wie in Abbildung 1 zu sehen.

Abbildung 1: Mit Escape-Sequenzen gestalten Sie den Zsh-Prompt bunt. Ein grünes Smiley signalisiert fehlerfrei Aktionen, ein rotes den Mißerfolg einer Befehlseingabe.
Interessante Optionen
Die Zsh besitzt einige Optionen, die Sie bei Bedarf mit dem Befehl setopt aktivieren. Soll die Option dauerhaft gelten, tragen sie setopt samt der gewünschten Parameter am besten in die zshrc ein. Dabei lässt sich der Parameternamen mit Groß- oder Kleinbuchstaben eingeben und meist auch durch Unterstriche gliedern. Zsh versteht hier also beispielsweise autocd ebenso wie AUTOCD oder Auto_cd.
Eine Liste aller Optionen finden Sie in der Manpage zshoptions. Eine gesetzte Option deaktivieren Sie wieder, indem Sie dem Parameternamen einfach ein “no” voranstellen: setopt no_Auto_cd oder setopt NOAUTOCD.
Um herauszufinden, welche Optionen gesetzt wurden, reicht ein einfaches setopt ohne Angabe eines Parameters. Zudem unterstützt setopt auch die Vervollständigung mittels [Tab] (“Tab Completion”). Möchten Sie zum Beispiel eine vollständige Liste aller Optionen angezeigt bekommen, drücken Sie nach Eingabe von setopt zweimal die Tabulator-Taste (siehe Abbildung 2). Die wichtigsten der rund 150 Optionen lauten:
AUTO_CD– Ist das erste Wort der Eingabe kein Befehl, so versucht Zsh in ein Verzeichnis dieses Namens zu wechseln. Mithilfe der Tab Completion macht dascdnahezu überflüssig.LIST_PACKED– Die Option verkleinert per Autovervollständigung ausgegebene Listen durch Anpassen des Spaltenabstands.SHARE_HISTORY– Gemeinsame Benutzung der Histories von mehreren Z-Shells; Befehle aus einer anderen laufenden Zsh werden dabei in die eigene History übernommen.GLOB– Die Z-Shell versucht, Muster (zum Beispiel ‘*’) aufzulösen. Bei einemls *ersetzen Sie durch Drücken von [Tab] also die Wildcard durch alle Dateien ersetzen.GLOB_COMPLETE– Normalerweise werden beispielsweise beim Drücken von [Tab] nach einemls *alle Dateien an die Stelle der Wildcard gesetzt. IstGLOB_COMPLETEaktiviert, wählen Sie durch mehrmaliges Drücken von [Tab] die gesuchte Datei aus (siehe auch MENU_COMPLETE).MENU_COMPLETE– Bei der Tab Completion fragt Zsh vor der Ausgabe verschiedener Möglichkeiten nicht mehr nach, sondern fügt sofort den ersten Treffer ein. Bei mehreren Treffern schalten Sie dann die einzelnen Ergebnisse mit [Tab] durch.CORRECT_ALL– Die Zsh versucht falsche Eingaben, wie zum Beispiel einfache Tippfehler, zu korrigieren.HUP– Beim Beenden der Shell wird ein HUP-Signal an die laufenden Prozesse geschickt. Ist diese Option nicht gesetzt, können Prozesse einfach weiter laufen.BEEP– Legt fest, ob die Z-Shell bei einer falschen Eingabe einen Piepston über den PC-Lautsprecher ausgibt.

Abbildung 2: Möchten Sie sich sämtliche verfügbaren Optionen der Z-Shell anzeigen lassen, dann rufen Sie dazu “setopt” auf und drücken zwei Mal die Tabulator-Taste.
Globbing
Zu den interessantesten Features der Zsh zählt ihr sehr mächtiges Globbing-System. Der Begriff Globbing leitet sich von der Funktionsweise des Tools glob ab und bezeichnet das Finden von Dateien und Ordnern nach Mustern, zum Beispiel mit Regulären Ausdrücken [2].
Mit dem Befehl setopt EXTENDEDGLOB aktivieren Sie das erweiterte Globbing: Sie können dann beispielsweise auch mit Argumenten wie <x-y> Bereiche von Zahlen auswählen. Zudem lassen sich mit Parametern wie (foo|bar) Argumente gruppieren, mit “**” stoßen Sie eine Rekursion durch den Verzeichnisbaum an:
% chmod 644 ~/public_html/ /*.h? tml(.)
Mit zusätzlichen so genannten Qualifiern modifizieren und verfeinern Sie das Suchergebnis. Dazu hängen Sie einen Qualifier nach dem Prinzip Muster(Qualifier) an das Suchmuster an. Möchten Sie etwa prüfen, bei welchen Programme in /usr/bin das SETUID-Bit gesetzt ist, geben Sie dazu den Qualifier “s” an:
ls /usr/bin/*(s)
Eine vollständige Liste der möglichen Qualifier finden Sie in der Manpage zshexpn. Die wohl am häufigsten eingesetzen Qualifier sind:
- “@” – filtert das Ergebnis nach symbolischen Links.
- “w” – gibt nur beschreibbaren Dateien aus.
- “W” – findet nur von allen Usern beschreibbare Dateien.
- “U” – filtert nach eigenen Dateien.
Abbildung 3 demonstriert einige Anwendungsmöglichkeiten für das Zsh-Globbing. Sie können das Ergebnis mit einem vorangestellten “^” negieren. So zeigt ls *(^U) ausschließlich solche Dateien an, die anderen Benutzern gehören.
Haben Sie für Ihre Zsh die Option EXTENDEDGLOB gesetzt, erweist sich der Modifier noglob in manchen Fällen als äußerst hilfreich. Er deaktiviert das Globbing für den darauf folgenden Befehl. So lädt der folgende Befehl nicht etwa die unter der URL vorhandene Seite herunter, sondern verursacht eine Fehlermeldung:
% wget http://www.foobar.de/inde?x.php?action=test zsh: no matches found: http://ww? w.foobar.de/index.php?action=test
Die Zsh interpretiert hier bei aktiviertem Globbing das Fragezeichen als Einleitung für ein Suchmuster. Mangels zu dem vermeintlich folgenden Muster passender Dateien gibt sie eine Fehlermeldung aus.
Setzt Sie aber dem Kommando ein noglob voraus, deaktiviert dies die Expansion nach Dateinamen – der Parameter wird also keiner entsprechenden Expansion unterworfen. Er geht statt dessen “ungefiltert” an wget, das dann die gewünschte Webseite herunterlädt:
% noglob wget http://www.foobar.?de/index.php?test
--11:41:25-- http://www.foobar.?
de/index.php?action=test
=> `index.php?action=?
test'
(…)
Weiterführende Quellen
Für den Fall, dass unsere kurze Einführung in die Zsh Sie dazu animiert hat, sich näher mit den Fähigkeiten der Z-Shell zu beschäftigen, mächten wir Ihnen noch einige weiterführende Informationsquellen ans Herz legen.
Dazu zählt last not least das Manual zur Z-Shell. Es wurde irgendwann derart umfangreich, dass man es in insgesamt 12 Manpages unterteilt hat, deren Namen alle mit “zsh” beginnen. Mit man zshall bekommt Sie alle Manuals am Stück, bei der Zsh 4.2.0 sind das dann etwa 100 KByte Text. Auf der offiziellen Site zur Z-Shell finden Sie eine kleine Zsh-Einführung [3] sowie die offizielle Zsh-FAQ [4].
Um einen Überblick über die Features der Zsh zu gewinnen und einen Vergleich zu anderen Shells zu bekommen, sollten Sie sich die Seite von Christian Schneider [5] ansehen. Eine herrvorragende Quelle für weitere Informationen bietet die deutschsprachige Zsh-Liebhaber-Seite [6] von Michael Prokop und Matthias Kopfermann. Hier wurden viele Beispiele gesammelt, die sich während der täglichen Arbeit wunderbar verwenden und abwandeln lassen. Außerdem sind dort viele weiterführende Links zu finden. Michael Prokop ist auch der Projektleiter der Linux-Live-CD GRML [7], welche die Zsh als Default-Shell verwendet. Zudem gibt es noch das kleinere Zsh-Lovers-Projekt, das Beispiele zu den in der Manpage beschriebenen Funktionen sammelt und als Zsh-Lovers-Manpage [8] zur Verfügung stellt.
Schließlich gibt es noch ein sehr gut geschriebenes englischsprachiges Buch, das den Umstieg von der Bash leichter macht: “From Bash to Zsh” (ISBN 1-59050-376-6) von Oliver Kiddle, Jerry Peek und Peter Stephenson ist bei Apress erschienen und kostet 35 US-Dollar. Falls es Ihnen aber zu lange dauert, in der Literatur nach Antworten zu suchen, können Sie sich auch direkt via IRC über die Channels #grml und #zsh im Freenode (irc.freenode.org) mit anderen Zsh-Benutzern austauschen. (jlu)
Infos
[1] RPMSeek: http://www.rpmseek.com
[2] Regular Expressions: Martin Möller, “Strukturierte Suche”, LinuxUser 08/2005, S. 90 ff.
[3] Zsh-Intro: http://zsh.sunsite.dk/Intro/
[4] Zsh-FAQ: http://zsh.sunsite.dk/FAQ/
[5] Christan Schneiders Zsh-Seite: http://www.strcat.de/zsh/
[6] Zsh-Liebhaber: http://michael-prokop.at/computer/tools_zsh_liebhaber.html
[7] GRML-Boot-CD: http://www.grml.org
[8] Zsh-Lovers: http://grml.org/zsh/#zshlovers





