Computer
Allerlei
vim
mutt
slrn
zsh
browser
icq
screen

 

Submenu:

Zsh - Generell
Zsh-Liebhaber

 

Quick-Index

Vorwort - Warum wurde diese Seite gemacht? - Fähigkeiten die an der Zsh faszinieren - Lokale Dateien - Literatur

Die Zsh-Liebhaber-Seite zsh liebhaber
        webpage

Siehe auch zsh-lovers-Projekt!

Vorwort

Willkommen zur Zsh-Liebhaber-Seite! Diese Webpage war ursprünglich unter www.infodrom.north.de/~matthi/zsh/ erreichbar. Gemeinsam mit Matthias Kopfermann habe ich (Michael) diese Webpage hierher verlagert, verbessert und aktualisiert. Redundanzen zu Zsh - Generell sind durchaus möglich und nicht ungewollt. Über Feedback an zsh-liebhaber@michael-prokop.at freuen wir uns!

Begonnen:         Fre Okt 17 13:00:00 CET 1997
Zuletzt editiert: Fri May  6 13:29:24 CEST 2005

Die Zsh (sprich Z-Shell) ist eine herausragende, aber im Verhältnis zur Bash ziemlich unbekannte Shell, also ein befehlsorientierter Eingabemechanismus, über den man vor allem Befehle unter Unix interaktiv eingeben und außerdem Befehle automatisieren und Abläufe programmieren kann. Sie ist im Falle der Zsh mit einer mächtigen Programmiersprache durchaus gleichzusetzen, wenn dabei auch kein Maschinencode erzeugt wird.

Warum wurde diese Seite gemacht?

Wir halten die Zsh für herausragend in Benutzerfreundlichkeit und Mächtigkeit. Sie macht das Arbeiten auf der Kommandozeile zur Freude, besticht durch ungeheure Anpassungsfähigkeit und hilft, wenn man sich einmal wieder nicht genau an irgendwelche Optionen bei Befehlen erinnere. Zusätzlich kann sie vieles, was andere Shells nur durch externe Befehle möglich machen. Ich (Matthias) selber stieß beim Lesen der Linux-Gazette zum ersten Mal auf die Zsh. Ein Benutzer hatte dort in einer Email zum Thema "Umwandlung von großen Buchstaben von DOS-Dateien nach Linux" eine sehr einfache und kurze Lösung durch die Zsh berichtet (siehe unten). Genau dafür ist die Zsh wie geschaffen. Man kann damit Probleme mit wenigen Tastenanschlägen lösen.

Auf einer Homepage über unterschiedliche Shells las ich (Matthias), die Zsh könne wahrscheinlich mehr als der Autor selber wisse. Natürlich hat das seinen Preis in der Größe der Shell und in der Größe des Handbuchs. Puristen werden die Zsh wohl nicht unbedingt benutzen. Aber wer sagt denn, dass man nicht in einer Sache Purist und in einer anderen sehr großzügig oder gar verschwenderisch sein kann oder dass man nicht für bestimmte Aufgaben so und für andere anders verfährt, je nach Bedarf, Speicherplatz, Rechnergeschwindigkeit?

Hier findet sich die Beschreibung der Z-Shell vom ihrem ursprünglichen Autor Paul Falstad, der übrigens durch einen Zhong Shao (heute Professor in Yale) mit Benutzername zsh auf diesen Namen kam. :)

Der ursprüngliche Autor beschrieb 1991 die Vorzüge dieser 1990 begonnenen Shell. Trotz seines Alters kann dieser längere Artikel Neugier wecken. Zumindest bei Sven Wischnowsky, einem der wichtigsten Zsh-Entwickler seit 1992 (ihm verdankt die Zsh ihre Vervollständigungsmechanismen und vieles mehr) und 1997 bei mir (Matthias) und 2002 bei mir (Michael) war der Artikel der Anlass, auf die Z-Shell umzusteigen. Und die Shell hat heutzutage noch so viele praktische Fähigkeiten dazu bekommen!

Seit 1999 gibt es diesen neuen Zsh-Guide von Peter Stephenson, einem anderen wichtigen Entwickler der Z-Shell, der mit großer Liebe zum Detail, mit Witz und - wie wir finden - sehr verständlich auf die Zsh und ihre Möglichkeiten eingeht. Seit Ende 2004 gibt es von Peter Stephenson sowie Oliver Kiddle und Jerry Peek ein Buch namens 'From Bash to Z Shell' das sich ausgiebig mit der zsh beschäftigt.

Leider ist diese tolle Shell, die es gerade Anfängern so viel leichter machen könnte und Power-Usern eine Unzahl an Möglichkeiten bietet, z.B. in Linux-Kreisen relativ unbekannt, obschon sie erhebliche Vorteile gegenüber der Bash hat und gegenüber der Tcsh auch eine ziemlich große Ähnlichkeit mit der Ksh und der Bourne-Shell aufweist und sich auch fuer Skripte ausgesprochen gut eignet.

Fähigkeiten, die an der Zsh faszinieren

  1. Man braucht kaum umzulernen: Die meisten Kommandos sind so, wie man sie von der Bash und der Ksh, die sie vor allem nachahmt, kennt. Oft kann man auch durch eine Beschreibung der Ksh eine Menge lernen. Diese ist nämlich in vielen älteren Unix-Büchern ausführlich beschrieben.
  2. Für Umsteiger bietet die Zsh einen Emulationsmodus für Sh, Csh und Ksh an. Beispielsweise versucht emulate sh, die SH zu emulieren. (siehe auch man zshbuiltins unter emulate.)
  3. Außerdem zwingt die Shell dem Anwender nie ein bestimmtes Verhalten auf. Mit über 150 Optionen lässt sich ihr Verhalten sehr flexibel an den Geschmack und die Bedürfnisse des Benutzers anpassen.
    So kann man mit der Z-Shell falsche Eingaben korrigieren lassen, ist aber dazu in keiner Weise gezwungen: (unsetopt correct) und die Vervollständigungen sind bis ins allerkleinste Detail anpassbar.
  4. Die Zsh ist ausgesprochen modular (über 25 Module). Damit ist der Nutzer in der Lage, ganz nach Bedarf bestimmte Features zu benutzen und andere völlig auszusparen.
    So hat die Zsh z.B. ein Mathematik-Modul mit über 30 mathematischen Funktionen, die viele nicht brauchen werden, für manche aber sehr nützlich sind. Gleiches gilt für das Profiler-Modul (zprof), ein mit den internen Vervollständigungen arbeitendes FTP-Modul (zftp), das Pseudoterminal-Modul zur Automatisierung von Programmen, die ein Terminal erwarten (zpty), u.s.w...
  5. Die Zsh kann Funktionen mit zcompile in eine für den Computer schneller zu lesende binäre Ausführungsform bringen. Dabei wird ein Word-Code ähnlich dem Java-Bytecode erzeugt, nur, dass dabei words (2 Bytes) benutzt werden. So kann man die Funktionen erheblich beschleunigen.
  6. Intuitiv (wie in Perl, Python, Ruby) lassen sich in Zeichenketten Ersetzungen durch Zeichenketten-Indizes machen:
    a="ich hab nix gemacht.";a[1]='I';a[-1]='. (Bart Simpson)'
  7. Die Zsh unterstützt assoziative Arrays (Variablen-Felder mit Buchstaben als Index):
    typeset -A ass_array; ass_array=(eins 1 zwei 2 drei 3 vier 4)
    deklariert und definiert eine auch Hash genannte Feldvariable, deren einzelne Elemente einen Index aus Buchstaben besitzen. print $ass_array[eins] gibt im Beispiel das erste Element, 1, aus, print ${(k)ass_array} gibt die Keys (Schlüssel), print ${(v)ass_array} die Values (Werte).
  8. Temporäre unbenannte Variablen ermöglichen es, Teile aus Zeichenketten zu extrahieren und alle möglichen Umwandlungen durchzuführen:
    print ${$( date )[1]}
    gibt das erste Wort, was date liefert, aus. Dazu muss der Befehl date in $() angegeben werden (die alte Bourne-Shell-Schreibweise innerhalb von `` funktioniert hier nicht!).
    $(date) wird umschlossen von ${[1]}, was das erste Wort hervorbringt. Diese Konstruktion kann man beliebig verschachteln, was nur den Nachteil besitzt, mit größerer Verschachtelungstiefe sehr unleserlich zu werden.
    print ${${$( LC_ALL=de_DE /sbin/ifconfig ppp0 )[5]}#Adresse:}
    könnte bei Verwendung von pppd unter Linux die IP-Adresse ausgeben, wobei nebem dem eben gezeigten Mechanismus zusätzlich die Zeichenkette "Adresse:" gelöscht wird.
    Es ist auch möglich, head, tail, uniq, sort und sogar grep durch interne Mechanismen zu ersetzen. Dazu muss so vorgegangen werden, dass der Modifier (f) im Index der unbenannten Variablen Verwendung findet. Dies führt dann dazu, dass bestimmte Zeilen statt Buchstaben durch den Index ausgewählt werden:
    print -l ${"$( < datei )"[(f)5]}
    gibt die Zeile 5 aus "datei" aus.
    print ${"$( < /etc/passwd )"[(fr)*root*]}
    gibt die erste Zeile, in der "root" vorkommt aus, wobei in diesem Fall im Index nach einem Muster (hier: "*root*") mittels (r) gesucht wird.
  9. Als regelrechtes grep mit allen Vorkommen kann man folgenden Mechanismus benutzen:
    print -l ${(M)${(f)"$(< /etc/passwd)"}##*$muster*} (f) 
    liest die in Anführungsstrichen stehende Ausgabe der Datei zeilenweise in eine unbenannte Variable. Wie auch in anderen Shells schneidet ## am Anfang *$muster* ab.
    Da aber (M) benutzt wird, werden alle Zeilen, bei denen das Muster zutrifft, nicht abgeschnitten, sondern alleine ausgegeben. Das Gegenstück dazu ist (R), was im vorigen Fall dann einem "grep -v" entspricht.
    Würde man nur ein # angeben, würden die Sterne (Stellvertreter für 0 oder mehr Zeichen) geizig - mit so wenig Zeichen wie möglich - ausgegeben. In diesem Fall würde dann also nur $muster selber ausgeben.
  10. Zsh kann wie bekanntere Programmiersprachen (Perl, Python, Ruby z.B) im Index einer Variablen ein "von_feld,bis_feld".
    print ${$( date )[2,4]}
    gibt vom zweiten bis vierten Wort das von "date" gelieferte Ergebnis aus. Oder es geht auch mit negativen Index:
    print ${${:-eins zwei drei vier fuenf}[2,-2]}
    gibt als Ergebnis zwei drei vier aus. (':-' ersetzt den fehlenden Variablennamen hier wie bei der Bash durch seine Werte).
    Bei Arrays ist es auch möglich, zweidimensionale Indizes zu gebrauchen:
    print ${$(date)[4][1,5]}
    gibt die Uhrzeit von date ohne Sekunden aus.
  11. Mit Hilfe des Moduls pcre kann die Zsh seit Version 4.1.1 Perls reguläre Ausdrücke verarbeiten. Dazu lädt man mit zmodload zsh/pcre das PCRE-Modul ein, kompiliert dann einen beliebigen perlartigen regulären Ausdruck mit Hilfe von pcre_compile und verarbeitet anhand des Fehlercodes 1 bzw. 0 alles weitere. Beispiel:
    pcre_compile '\s\d\.\d{3}\.\d{3} Euro' &&\
    pcre_match ' 1.000.000 Euro'\
    && echo "Trifft zu!" || echo "Trifft nicht zu!"
    Bei komplexeren Ausdrücken kann man die Geschwindigkeit noch durch pcre_study verbessern.
  12. Mit dem sogenannten Here-String kann man eine Art Here-Document benutzen ohne ein EOT-Signal auf einer Extra-Zeile eingeben zu müssen:
    for Programm in cat tail head grep ; do >> /tmp/datei  \
    <<< "Hallo,Welt! Ich habe das Geüfhl, mein             \
    externes $Programm wird bald nicht mehr so viel benutzt." ; done
    Man achte auch auf das Auslassen von cat, was bei der zsh nicht mehr nötig ist!
  13. Fließkommazahlen können berechnet werden:
    printf "%.0f\n" $[ 2.8*15 ]
    Ausserdem kann in verschiedenen Zahlensystemen gerechnet werden, in dem in eckigen Klammern [#<zahlensystem>] geschrieben wird, also:
    for (( i=1; i<100; i++ )) { print $(( [#10] i)) }
    entspricht
    $(( [#16] i )) }
    Bei zweifacher Angabe von # wird das Zahlensystem nicht ausgegeben.
    Sogar einen "Taschenrechner" gibt es in der Zsh, der nach autoload zcalc zur Verfügung steht.
  14. Die Zsh kann alles vervollständigen, was man sich so ungefähr vorstellen kann. (siehe auch zshcompctl und seit 3.1.6 zshcompsys . (Programmierbare Vervollständigung ist für die Bash erst seit April 2000 (Version 2.04) und bei der Ksh gar nicht vorhanden. Seit Zsh 4.1 können sogar die Vervollständigungsmechanismen der Bash genutzt werden unter Verwendung von bashcompinit.)
    Mit der Version 3.1.6 wird eine neue Richtung in der Programmierung von Vervollständigungen vorgelegt.
    Statt mit Optionen lässt sich der Ergäzungsmechanismus der Shell nun sehr viel einfacher durch den Aufruf von über 400 vordefinierten Funktionen programmieren.
    Das hat den Vorteil: Für sehr viele Bereiche lässt sich durch Kopieren und Editieren schnell eine neue Vervollständigung fertigstellen, da man jetzt nicht mehr so detailiert wissen muss, wie die neuen Vervollständigungen zu programmieren sind. Außerdem muss man häufig sogar einfach nur mit autoload compinit && compinit den neuen Mechanismus blind in Gang setzen und kann direkt vorgefertigte Vervollständigungs-Mechanismen nutzen. Man rufe danach beispielsweise einmal xterm -fn «TAB»auf. (Siehe auch hier)
    Beispiele zur Vervollständigung (noch nach dem alten Schema bis 3.1.5):
    compctl -g '*(/)' cd 
    macht aus einer einfachen Dateiergänzung wie der Ksh eine intelligente Vervollständigung für "cd", die nur noch Verzeichnisnamen aufführt.
    Vor allem mit compctl -k '(`aktion`)' lassen sich sehr praktische Vervollständigungsmechanismen erstellen. Man kann sich so z.B. ohne Probleme bei Aufruf eines Email-Programmes nur Email-Adressen und mit ftp nur FTP-Adressen vervollständigen lassen. Außerdem kann man bei der Vervollständigung auch Dateienden abschneiden lassen. Das ist z.B. bei Java sehr praktisch.
    compctl -g '*.class(:r)' java
    (Mehr Beispiele zur älteren Vervollständigung hier)
  15. Mit der Zsh kann man sehr gezielt nach Worten in Dateien suchen: Nach dem Freischalten von Sonderzeichen für die Reichweite eines glob-Befehls mit setopt extended_glob ist folgendes machbar:
    grep Wort *~(*.gz|*.bz|*.bz2|*.zip|*.Z)
    sucht 'Wort' nicht mehr in den komprimierten Dateien im Mail-Ordner.
    ~ bedeutet hier so viel wie "außer".
    Alle Dateien, die nicht die Endung *.bz2 und auch nicht *.gz enthalten , sucht man mit
    ls ^(*.bz2|*.gz)
    Das ^ ist also das "NICHT", das Ausrufezeichen wird von der Zsh für alte Befehle benutzt.
    An dieser Stelle bietet sich vielleicht ein globales Alias für komprimierte Dateien an (siehe weiter unten).
    Zusätzlich zu ^ und ~ lassen sich die Ausdrücke # und ##benutzen, um null und mehr bzw. ein und mehr Vorkommen des Zeichens davor zu erhalten, was bei Perls regulären Ausdrücken den Zeichen * bzw. + entspricht.
  16. Globale Aliase sind Aliase, die nicht nur am Anfang der Kommandozeile oder nach ; als Aliase wirken können. Sie sollten gut gekennzeichnet werden:
    alias -g §k="*~(*.bz2|*.gz|*.tgz|*.zip|*.z)"
    und danach der Befehl
    ls -d §k 
    listet alle nicht-komprimierte Dateien auf.
    Mit unalias '§k' wird man dieses globale Alias wieder los. Wichtig hierbei sind die einfachen Anführungsstriche. Sonst wirkt nämlich §k weiter, was nicht im Sinne des Benutzers wäre.
  17. Aliase können seit Version 4.2 auch verwendet werden, um bestimmten Zeichenketten-Endungen (Suffixes) nach einem Punkt automatisch mit dem selben Befehl aufzurufen, was meist für Dateiendungen benutzt wird. Dabei gilt:
    alias -s NAME=WERT
    wobei TEXT.NAME dann durch die Zsh zu WERT TEXT.NAME wird.
    alias -s txt='less -rE'
    ruft alle ohne Befehl aufgerufenen .txt-Dateien automatisch mit dem Befehl less -rE auf, so dass man jetzt einfach nur den Dateinamen und ein return eingeben muss. Diese Funktionalität ist vergleichbar mit dem Anklicken einer oder mehrerer Dateien mit einem graphischen Dateimanager. Dabei kann man auch globale Zeichen wie * verwenden, also beispielsweise *.txt und ein "enter" eingeben um alle Dateien mit Endung ".txt" mit less zu lesen.
    Praktischerweise gibt es mit autoload zsh-mime-setup ; zsh-mime-setup die Möglichkeit, anhand der Mime-Definitionen in /etc/ schon bestimmte Datei-Endungen mit bestimmten Programmen zu belegen.
    alias -s de=w3m
    alias -s at=w3m
    ruft alle WWW-Seiten mit .de oder .at direkt mit w3m auf. ('.de' bzw. '.at' in der Eingabe ist in diesem Fall keine Dateiendung!)
  18. In der Zsh kann man aus jeder eigenen Funktion eine Datei machen, ohne dass diese Datei ausführbar sein muss. Hierzu setzt man die Variable FPATH bzw fpath (siehe unten) auf das oder die Verzeichnisse, die berücksichtigt werden sollen.
    In der Datei genügt es, einfach eine oder mehrere Funktionen zu schreiben, z.B:
    begruessung() { echo "Hallo, $1" ; }
    herzlich()    { echo "Ist ja riesig, $1, Dich zu sehen" ; }
    Jetzt muss noch dieser Dateiname mit autoload dateiname bekannt gemacht werden. Daraufhin stehen nach einmaligem Aufruf des Namens der Funktionen die beiden Funktionen dann zur Verfügung. Schreibt man nur den Funktionsrumpf allein dann hat das gegenüber dem Schreiben von Funktionen den Vorteil, sofort ausgeführt werden zu können. autoload-Funktionen müssen nämlich erst einmal aufgerufen werden, damit ihr Rumpf bekannt ist. Beispiel:
    echo "Ist das schön, $1, Dich zu sehen\!" > ~/.zsh/funktionen/begruessung
    ist nach Aufruf von autoload begruessung sofort nutzbar. (Siehe AUTOLOADING FUNCTIONS unter 'man zshmisc')
  19. Statt in eine "Backslashitis" beim Aufschreiben von Skalar-Variablen mit viel Inhalt zu verfallen (z.B. beim Definieren des Pfades) gibt es bei der Zsh die Möglichkeit, das kleinbuchstabige Gegenüber des großbuchstabigen Variablennamens als eines Arrays zu verwenden und sogar für eigene Variablen mit typeset -T ein "Gegenüber" von einer Skalar-Variable zu einer Feld-Variable durch die Kleinschreibweise der Variablen zu erzielen.
    Dieser Variante kann man dann ein Feld aus Werten - durch Leerzeichen oder Zeilenumbruch getrennt - zuweisen. Beispiel PATH:
    alt: PATH=/usr/bin\
         :/usr/local/bin/\
         :/usr/sbin\
         :/usr/local/sbin\
         :/usr/X11R6/bin
    
    zsh: path=( /usr/bin /usr/local/bin /usr/sbin /usr/local/sbin /usr/X11R6/bin )
    Da die Zsh für Feldvariablen runde Klammern braucht (wenn nicht setopt shwordsplit gesetzt ist) sind die Worte in runde Klammern eingeschlossen.
    Wer allerdings kompatibel zur Sh/Ksh/Bash programmieren muss/will, der muss die Option setopt shwordsplit setzen.
  20. Zle - der Zeileneditor der Zsh - ist den Zeileneditoren anderer Shells überlegen. Hier kann man fröhlich mehrere Zeilen schreiben und nach dem Aufruf mit RETURN separat einzelne Zeilen korrigieren. Man muss also nicht mehr immer einen externen Editor aufrufen.
    Besonders nett dabei: Wo die Bash nur das Manövrieren wie in einer einzigen Zeile zulässt, kann man bei der Zsh bequem mit dem Cursor - wie in einem Editor - über mehrere Zeilen navigieren.
    Will man innerhalb mehrerer Zeilen editieren, dann muss man entweder mit bindkey "^Xp" push-line-or-edit oder ähnlicher Tastenbelegung diesen Puffer in einen anderen Puffer kopieren oder aber nach einem Control-C erneut die Zeilen zurückholen.
  21. Mittels zle -N kann man eigene, sogenannte Widgets (das sind Editier-Funktionen) zle bekannt machen. In den Variablen LBUFFER und RBUFFER liegt die Kommandozeile links bzw. rechts des Cursors, die man so sehr einfach manipulieren kann. Beispiel:
    klammer() { LBUFFER="\${$LBUFFER" ; RBUFFER="}$RBUFFER" }
    erzeugt eine Funktion klammer, die man mit bindkey '^g' klammer jetzt an die Taste Control-G zuweisen kann.
    Noch ein Beispiel für ein User-Widget:
    wohin() {
      dirs -v
      print -n "Wohin? "
      read WOHIN
      cd +${WOHIN:=0}
    }
    Jetzt muss mit 'zle -N ' "wohin" als User-Widget deklariert werden. Anschließend kann mit 'bindkey '^Ww' wohin' die definierte und deklarierte Editier-Funktion auf 'Control-Ww' gelegt werden.
    Zusätzlich kann man mit 'autoload zed' sogar einen Editor (der in der Z Shell selber geschrieben ist) benutzen, der dann von seiner Voreinstellung oder durch 'bindkey -e' Emacs-artig, bei Eingabe von 'bindkey -v' vi-artig funktioniert. Gesichert wird allerdings durch 'control-x control-w' oder im Vicmd-Modus mit 'ZZ' und mit dem Befehl control-c bricht man ab. Ruft man zed mit der Option -f oder als fned auf, kann man Funktionen editieren.
    Als wohltuend empfinden wir bei einem Kommando des Zeileneditors das Kommando insert-last-word, das im Gegensatz zur Bash nicht immer das letzte Wort, sondern bei wiederholtem Aufruf das letzte Wort davor und so weiter aufruft. (Siehe auch 'man zshzle')
  22. Die Zsh unterstützt wie ihr Vorbild -die Ksh- Koprozesse. Koprozesse sind eine Möglichkeit, an Parallelprozesse Daten zu übergeben und Daten zu empfangen. Diese Koprozesse werden allerdings mit 'coproc' eingeleitet und nicht wie bei der Ksh mit |& .
    Mit ' print -p' und mit '>&p ' als Umlenkung kann ich Daten an den Prozeß senden und mit 'read -p und '<&p' als Umlenkung Daten von diesem Prozeß auslesen. Beispiel:
    coproc ed /tmp/notizen
    print -p "a"
    ls -l >&p
    print -p ".\nwq"
    schreibt in einen parallel laufenden Koprozess, den altehrwürdigen Ed, die Ausgabe von 'ls -l' und speichert den Inhalt in der Datei /tmp/notizen ab und beendet ed.
    Weitgehender als ein Coprozess ist das Laden des zpty-Moduls mit 'zmodload zsh/zpty', welches dann ähnliche Steuerungsmöglichkeiten wie das Programm expect bietet. Als Beispiel für die Verwendung von zpty kann das Skript nslookup in /usr/share/zsh/4.x.x/functions/ dienen, was das gleichnamige interaktive Programm durch seine Vervollständigung leichter bedienbar macht.
  23. Die Zsh kennt die Formatierungen, die die Ksh kennt. typeset - oben schon kurz bei assoziativen Variabelfeldern erwähnt - ist ein mächtiger Formatierbefehl der Ksh. Mit diesen Formatierungsregeln lassen sich Ausgaben auf unterschiedliche Weise formatieren.
    typeset -L2 name=werteintrag ;print "[$name]"
    gibt linksformatiert "[we]" aus, die ersten 2 Buchstaben, umrahmt von [].
    typeset -lL20 name=WERT;print "[$name]"
    gibt in Kleinbuchstaben (-l für lower) "[wert         ]" aus, wobei 20 - 11 Leerzeichen eingefügt werden.
    typeset -r RPROMPT=%n
    schützt den Rechtsprompt vor einem versehentlichen Überschreiben. Die Variable ist jetzt read-only und zsh warnt einen mit "zsh: read-only variable: RPROMPT ". Alle typeset-Befehle können mit einem - statt dem + aufgehoben werden. (Siehe man zshbuiltins unter typeset)
    Zusätzlich zu typeset kann man auch durch sogenannte Modifier die Ausgabe von print verändern. Beispiel:
    name="Wert"
    print "[${(Ll:20:)name}]"
    ergibt genau die selbe Ausgabe wie
    typeset -lL20 name
    Seit Zsh 4.1.1 kann man mit
    printf "%20s\n" ${(L)a}
    ähnlich wie in der gleichnamigen C-Funktion auch dieses Ergebnis bekommen, ohne den externen printf-Befehl nutzen zu müssen.
  24. Die Ausgabe von Dateinamen kann mittels sogenannter Qualifier spezifiziert werden (siehe man zshexpn unter Glob Qualifier). Beispiele:
    print -l *(m-1) # listet nur Dateien zeilenweise auf, die vor
                    # bis zu einem Tag modifiziert wurden
    
    print -l *(a1)  # listet Dateien zeilenweise auf, auf die vor einem
                    # Tag zugegriffen wurde
    
    print -l *(@)   # listet nur die Links zeilenweise auf
    
    ls -doF *(/)    # findet nur die Verzeichnisse
    
    chmod 640 *(W)  # verändert die Rechte aller Dateien, in die
                    # jeder schreiben darf, denn das ist ja meistens
                    # besonders riskant!
    
    
    grep name *(.)  # findet nur noch reine Dateien. Damit ist
                    # die unsinnige Meldung "grep: bla: Is a directory"
                    # für alle Zeiten vermeidbar.
    
    Um einmal wieder an alte schlechtere Zeiten erinnert zu werden, könnte man auch 'grep name *(^.@)' eingeben. Hiermit werden alle Dateien aufgelistet, mit denen grep nichts anfangen kann, denn '^' ist das Nicht-Zeichen :).
    gg() { grep -wE "$1" *(.) | less -r }
    könnte eine kleine Zsh-Funktion sein, um gezielt nach einem Wort und unter Zuhilfenahme von regulären Ausdrücken zu suchen. Ich persönlich (Matthias) benutze allerdings lieber Perl für solche Dinge und habe dafür das Perl-Programm mg entdeckt.
  25. Ein sehr schneller Befehl, um DOS-Dateien (keine Verzeichnise) zu Dateien mit kleinen Buchstaben zu machen ist:
    for i in [A-Z][A-Z]*(.); do mv $i ${i:l} ;done
    Der Qualifier :l (für lowercase) leistet hier ganze Arbeit.
    print -l *(LM+3)
    gibt zeilenweise Dateien aus, die über 3 Megabyte groß sind.
  26. Ich kann unter der Zsh komprimierte Email-Pakete lesen, ohne mich zuerst um das Entpacken kümmern zu müssen. Das geht bei gzip-gepackten Dateien z.B. so:
     mutt -f =(zcat mailfold*.gz)
    In den =() steht dabei die Aktion, die mit einer Datei gemacht wird, es wird dabei eine temporäre Datei erzeugt und mit ihr z.B. mutt -f aufgerufen. Ein anderes Beispiel:
    mutt -f =(grepmail "Mustafa Mustermann" ~/mbox)
    sucht alle Emails von Mustafa Mustermann aus einer sehr großen Email-Datei namens mbox mittels grepmail, einem sehr mächtigen Perl-Programm zum Herausfiltern von Emails, welche einem bestimmten Kriterium entsprechen, heraus. Die temporäre Datei wird selbstverständlich nachher wieder gelöscht.
    mutt ist ein sehr schönes Mail-Programm, welches auch auf der Kommandozeile funktioniert, das wir sehr empfehlen können. Mit 'mutt -f' liest mutt nicht aus /var/spool/mail sondern die Email-Datei, hier mehrere Emaildateien. Ein anderes Beispiel:
    lynxbzgrep() {
      lynx -force_html -dump =(bzip2 -cd $1 | grep $2)
    }
    ermöglicht es, mit lynxbz bzip2-gepackte HTML-Seiten nach einem Begriff zu untersuchen. Nötig wird dieser Mechanismus, wenn ein Programm lseek benötigt. (Siehe man 3 lseek)
    Wird keine temporäre Datei benötigt, dann kann man wie auch bei der Bash '<()' verwenden. Damit erspart man sich dann die manuelle Verwendung von /proc/self/fd oder die manuelle Erzeugung einer "named pipe":
    lynx -force_html <( gzip -cd komprimiert.html.gz )
    ist ein Beispiel, bei dem lynx die Ausgabe von 'gzip -cd komprimiert.html.gz' verarbeitet.
    Durch intelligente Kommunikation verschiedener Prozesse wird es möglich, dass man zwei Pseudodateien erzeugen und miteinander vergleichen kann: In Shellkreisen wird dies als 'named pipe' bezeichnet, die die Zsh indirekt erzeugt.
    diff <(zcat erste_datei.gz) <(zcat zweite_datei.gz)
    vergleicht den Inhalt von zwei komprimierten Dateien miteinander.
  27. Nach Setzung von READNULLCMD=less lässt sich eine Datei mit:
    < datei
    unter less angucken. Einfach ein < vor die Datei setzen.
  28. Es ist ohne Probleme möglich, die Standardausggabe an mehrere Dateien umzulenken:
    ls >datei1 >datei2 >datei3
    oder:
    ls >> datei1 >> datei2
  29. Man kann auch die Standardeingabe von mehreren Dateien empfangen:
    less < datei1 < datei2
  30. Es ist möglich, eine Umlenkung in eine Datei und gleichzeitig an eine Pipe zu bewerkstelligen:
    make >logfile | grep Error
  31. Mit ls -lL =emacs kann man beispielsweise in jedem Verzeichnis schauen, wie groß 'emacs' genau ist. Man muss nicht mehr den Pfad angeben. Die Zsh schaut dabei selbst im Pfad nach, wenn man emacs im Pfad hat. Man kann auch bequem Dateien, die im Pfad stehen, auf diese Art editieren.
    jed =genial.c
    editiert eine C-Funktion, wenn sie im Pfad gefunden werden kann.
  32. Statt eines sehr expliziten aber umständlich zu tippenden find-Befehls kann under der Zsh ** als rekursives Kürzel verwendet werden. Mit:
    print -l **/*.html
    findet man alle HTML-Seiten, die in allen Verzeichnissen unterhalb des jetzigen Verzeichnisses vorhanden sind und gibt sie auf je einer Zeile (-l) aus (**=Rekursion). Weitere Beispiele:
    print -l **/*(.)
    ist das Äquivalent zu:
    find -type f
    print -l **/datei.html # sucht die bestimmte Datei in allen
                           # vom aktuellen Verzeichnis abgehenden
                           # Verzeichnissen und gibt genau sie aus.
    
    print -l **/*.html~datei.html # gibt alle HTML-Seiten
                                  # mit Ausnahme von datei.html zeilenweise aus.
    
    grep name **/*.txt  # sucht in allen Texten unterhalb des
                        # gegenwärtigen Verzeichnisses nach Dateien
                        # mit Endung .txt.
    
  33. Mit vared kann man alle Umgebungsvariablen editieren. Das finden wir praktisch, weil wir sofort die Variable erreichen und nicht erst in einer Datei wie .zshrc nach ihr suchen müssen. Außerdem wirkt das Editieren der Variablen natürlich sofort.
  34. Der Befehl dirs -v zeigt alle Verzeichnisse, in denen man in einer Sitzung gewesen ist zeilenweise an. Wenn man
    setopt autopushd setzt, kann man nun mit cd +2 das vorletzte Verzeichnis erreichen.
  35. Mit der Zsh kann man sehr lange Unterverzeichnisse im Prompt mit einem kurzem oder signifikanteren Namen (named directory) versehen und dann mit ~name aufrufen. Das ist insbesondere dann sehr praktisch, wenn man in einem sehr entfernten Ordner von '/' aus gesehen arbeitet.
    Ich (Matthias) habe mir eine kleine Zsh-Funktion geschrieben, die mir aus einem langem Verzeichnisnamen einen kurzen erzeugt:
    zza () {
      NAMED_DIRECTORY=$PWD:t; # der Name des jetzigen Verzeichnisses wird
                              # an NAMED_DIRECTORY ohne die Hierarchie übergeben.
                              # :t steht für tail.
      eval $NAMED_DIRECTORY=$PWD; # es findet die Setzung eines named directory statt.
      cd ~$NAMED_DIRECTORY;       # es wird in das named directory gesprungen.
                                  # ist mit dem bestehenden Verzeichnis identisch
                                  # aber der Name ist kürzer im Prompt.
    }
    
    Eine außerdem sehr praktische Möglichkeit besteht darin, dass man jetzt nicht mehr den ganzen Pfadnamen angeben muss, wenn man eine Datei verschiebt. Z.B.:
    mv datei.1 ~lm1
    könnte die Datei bequem nach /usr/local/man/man1/ verschieben, wenn man lm1=/usr/local/man/man1 gesetzt hat.
    Bei der Prompt-Darstellung gibt es zwei Möglichkeiten: Entweder weisst man am Ende auch noch den letzten Slash zu: info=/usr/local/info/ Dann wird im Prompt der ganze Name dargestellt. cd ~info springt zwar nach /usr/local/info, aber im Prompt steht:
    /usr/local/info%
    Möchte man aber den kurzen Prompt haben, dann muss man so zuweisen:
    info=/usr/local/info
    -also ohne Slash am Ende.
  36. Die Option autocd erlaubt es, nur den Namen eines Ordners anzugeben. Bei Eindeutigkeit wird dann sofort in diesen Ordner gesprungen. Z.B. springt bin «enter» dann sofort in das bin-Verzeichnis.
  37. Es gibt keinen Fehler bei Farbprompts wie unter der Bash1-Shell. Gerade bei der Gliederung des Prompts ist das besonders wichtig. Da die üblichen Escape-Sequenzen sehr unleserlich sind gibt es in der Zsh eine besonders elegante Möglichkeit, um Farben zu definieren. Ein Beispiel:
    autoload -U colors && colors
    echo "$fg_bold[red]zsh $fg_no_bold[white]is $bg[blue]$fg_bold[green]nice"
  38. Mit RPROMPT lässt sich ein PROMPT auf der rechten Seite definieren:
    RPROMPT=%l zeigt beispielsweise an, auf welchem Rechner man sich befindet.
    RPROMPT=%n zeigt den Benutzer an.
    RPROMPT=%T zeigt die Zeit an.
    RPROMPT=%D{%d.%m.%y} zeigt das Datum nach deutscher Darstellung an.
  39. Selbstverständlich kennt die Zsh auch eine Korrekturmöglichkeit bei falscher Eingabe, die aber nur dann wirksam wird, wenn man das wirklich eingestellt hat. Man setzt in einen solchem Fall einfach:
    setopt autocorrect
    Die Korrektur kann durch Setzung eines
    alias <befehl>=nocorrect <befehl>
    verhindert werden.
  40. Um darüber informatiert zu werden, wer alles außer mir sich eingeloggt hat, gibt es das Kommando watch wie unter der Tcsh.
    watch=(notme)
    listet z.B. alle Benutzer auf, die nicht ich sind :)
    Hierbei kann das Format der Ausgabe geändert werde:
    WATCHFMT='%n eingeloggt auf Terminal %l von %M seit %T '
    Wählt man watch=(@vorsicht_ist_angesagt), so werden alle Benutzer aufgeführt, die von dem Server vorsicht_ist_angesagt eingeloggt sind.
    Positiv herum kann man so natürlich auch alle Freunde erkennen lassen:
    watch=( < ~/.freunde root)
    liest alle Freunde aus der Datei .friends in das Feld watch zusätzlich zu root ein. So kann man schnell erkennen, wenn sich Freunde einloggen.
  41. Es gibt in der Zsh einen sehr bequemen Wiederholungsbefehl, der von der tcsh abgeschaut ist: repeat. Möchte man z.B. einen Werbemailer böswillig strafen, dann könnte man das so machen:
    repeat 100 mail -s "spams suck" badcompany@devilsheart.com < flame
    Dabei sollte allerdings bedacht werden, dass man damit meist harmlose Benutzer trifft, die schlechte Passworte haben und deshalb Räubern auf den Leim gegangen sind.
  42. Ruft man ein altes Kommando mit !?kommando auf, hat man die Möglichkeit, vor der erneuten Ausführung zu schauen, ob es sich hierbei auch um das gewünschte Kommando handelt. Man drückt dazu einfach «TAB». Ebenso kann man sich auch die genau betroffenen Dateien eines global wirkenden Befehles (z.B. 'ls *.html') mit «TAB» ansehen.
  43. Gerade eben getippte Worte auf der Kommandozeile können mit !# genauer wiedergegeben werden als bei Bash/Tcsh/Ksh. Man gibt einfach an, wo wiederholt werden soll - z.B.:
    echo ein_langes_wort zweites_langes_wort drei !#1-2
    schreibt auf den Bildschirm: 'ein_langes_wort zweites_langes_wort drei ein_langes_wort zweites_langes_wort'.
  44. Um die Funktion funct alle 300 Sekunden auszuführen führt man einfach folgenden Befehl aus:
    periodic funct()  PERIOD=300 fortune -s
    Anmerkung: Allerdings muss dazu auch am Prompt ein Befehl eingegeben werden, sonst kann man natürlich nichts auf dem Bildschirm sehen.
  45. Die Zsh kennt den '..' Operator von Pascal (und Perl):
    echo {1..7} "\nWo ist denn die Bash geblieben?"
    ergibt:
    1 2 3 4 5 6 7
    Wo ist denn die Bash geblieben?
  46. Die Zsh hat in ihrer sehr mächtigen HISTORY CONTROL ein run-help Kommando, mit dem zu einem Buffer gezielt Informationen abgerufen werden können. Voreingestellt ist hier der Aufruf der Manpage zu dem Kommando. Verändern könnte man diesen Aufruf, in dem man einfach aus:
    alias run-help=man # ein ->
    alias run-help=info
    macht.
    man_zshall() man zshall  # und nachfolgendes Deklarieren von
    zle -N man_zshall        # kann durch Definition von
    bindkey '^g' man_zshall  # nun immer bei Control-G ausgeführt werden.
  47. sched ist ein interner Befehl zum automatischen, zeitgebundenen Abarbeiten von Kommandos ähnlich wie bei 'at'. Dabei werden die Kommandos aber nicht ausgeführt und dann als E-Mail zugeschickt, sondern gelangen erst einmal in den Puffer und werden beim nächsten Kommando erst auf dem Bildschirm ausgegeben.
    sched +0:10 figlet "Du musst jetzt los"
    führt in 10 Minuten in Großschrift auf dem Bildschirm eine Warnung zum Gehen aus. Dabei ist allerdings das Durchführen des Befehls abhängig von der Eingabe eines nächsten Befehls.
  48. Wer jetzt von der Z-Shell endgültig überzeugt ist und den Umstieg von z.B. der Bash wagt sollte sich die Bemerkungen von Matthias zum Umstieg von der Bash auf die Z-Shell durchlesen.

Lokale Dateien

Folgende Dateien wurde von Matthias erstellt bzw. gesammelt: Die Zsh-Generell-Webpage von Michael ist auch via obiger Navigation erreichbar.

Literatur

Zsh-Homepage/Download

Englische Artikel

Hilfreiches

Live-CDs mit Zsh

Diese Seite verlinken?
http://www.michael-prokop.at/computer/tools_zsh_liebhaber.html

Bekennender Zsh-Liebhaber? Nutze einen dieser Button:
zsh liebhaber
        webpage   zsh lover

Die Autoren dieser Webpage (Matthias Kopfermann und Michael Prokop) sind via zsh-liebhaber@michael-prokop.at erreichbar! Feedback ist willkommen!

* Nach oben