6 zsh-lovers - tips, tricks and examples for the Z shell
14 Whenever we look at the zsh manual we wonder why there are no examples or those
15 simply things in (shell) life. The zsh contains many features, but there was no
16 manpage with some examples (like procmailex(5)). That's why we wrote this
19 Most of the tricks and oneliner come from the mailinglists zsh-users,
20 zsh-workers, google, newsgroups and from ourself. See section *LINKS* for
23 Note: This manpage (zsh-lovers(1)) is *not* an offical part of the Z shell! It's
24 just a just for fun - manpage ;) +
25 For comments, bugreports and feedback take a quick look at the section *BUGS*.
29 This section provides some examples for often needed shellscript-stuff. Notice
30 that you should not use otherwise most examples won't work. +
31 Parse options in shellscripts. Example taken from ZWS by Adam Chodorowski
32 (http://www.chodorowski.com/projects/zws/[]):
33 ----------------------------------------------
40 zparseopts -K -- p:=o_port r:=o_root h=o_help
41 if [[ $? != 0 || "$o_help" != "" ]]; then
42 echo Usage: $(basename "$0") "[-p PORT] [-r DIRECTORY]"
50 if [[ $root[1] != '/' ]]; then root="$PWD/$root"; fi
52 # now use the function:
54 ----------------------------------------------
58 Available subsections are *Aliases*, *Completion*, *Unsorted/Misc examples*,
59 *(Recursive) Globbing - Examples*, *Modifiers usage*, *Redirection-Examples*,
60 *ZMV-Examples* and *Module-Examples*.
64 Suffix aliases are supported in zsh since version 4.2.0. Some examples:
70 Now pressing return-key after entering 'foobar.vim' starts vim with
71 foobar.vim. Calling a html-file runs browser w3m. 'www.zsh.org' and pressing
72 enter starts w3m with argument www.zsh.org. +
73 Global aliases can be used anywhere in the command line. Example:
74 ----------------------
75 $ alias -g C='| wc -l'
76 $ grep alias ~/.zsh/* C
78 ----------------------
79 Some more or less useful global aliases (choose whether they are useful or not
81 --------------------------------------------------------
83 alias -g ....='../../..'
84 alias -g .....='../../../..'
85 alias -g CA="2>&1 | cat -A"
87 alias -g D="DISPLAY=:0.0"
89 alias -g ED="export DISPLAY=:0.0"
90 alias -g EG='|& egrep'
93 alias -g ELS='|& less -S'
94 alias -g ETL='|& tail -20'
99 alias -g HL='|& head -20'
100 alias -g Sk="*~(*.bz2|*.gz|*.tgz|*.zip|*.z)"
101 alias -g LL="2>&1 | less"
103 alias -g LS='| less -S'
106 alias -g NE="2> /dev/null"
107 alias -g NS='| sort -n'
108 alias -g NUL="> /dev/null 2>&1"
110 alias -g R=' > /c/aaa/tee.txt '
111 alias -g RNS='| sort -nr'
113 alias -g TL='| tail -20'
115 alias -g US='| sort -u'
116 alias -g VM=/var/log/messages
117 alias -g X0G='| xargs -0 egrep'
118 alias -g X0='| xargs -0'
119 alias -g XG='| xargs egrep'
121 --------------------------------------------------------
125 See also man 1 zshcompctl zshcompsys zshcompwid. zshcompctl is the old
126 style of zsh programmable completion, zshcompsys is the new completion
127 system, zshcompwid are the zsh completion widgets.
129 Some functions, like _apt and _dpkg, are very slow. You can use a cache
130 in order to proxy the list of results (like the list of available
131 debian packages) Use a cache:
132 ---------------------------------------------------------------------------------------------------
133 zstyle ':completion:*' use-cache on
134 zstyle ':completion:*' cache-path ~/.zsh/cache
135 ---------------------------------------------------------------------------------------------------
137 Prevent CVS files/directories from being completed:
138 ---------------------------------------------------------------------------------------------------
139 zstyle ':completion:*:(all-|)files' ignored-patterns '(|*/)CVS'
140 zstyle ':completion:*:cd:*' ignored-patterns '(*/)#CVS'
141 ---------------------------------------------------------------------------------------------------
143 Fuzzy matching of completions for when you mistype them:
144 ---------------------------------------------------------------------------------------------------
145 zstyle ':completion:*' completer _complete _match _approximate
146 zstyle ':completion:*:match:*' original only
147 zstyle ':completion:*:approximate:*' max-errors 1 numeric
148 ---------------------------------------------------------------------------------------------------
150 And if you want the number of errors allowed by _approximate to
151 increase with the length of what you have typed so far:
152 ---------------------------------------------------------------------------------------------------
153 zstyle -e ':completion:*:approximate:*' \
154 max-errors 'reply=($((($#PREFIX+$#SUFFIX)/3))numeric)'
155 ---------------------------------------------------------------------------------------------------
157 Ignore completion functions for commands you don't have:
158 ---------------------------------------------------------------------------------------------------
159 zstyle ':completion:*:functions' ignored-patterns '_*'
160 ---------------------------------------------------------------------------------------------------
162 With helper functions like:
163 ---------------------------------------------------------------------------------------------------
164 xdvi() { command xdvi ${*:-*.dvi(om[1])} }
165 ---------------------------------------------------------------------------------------------------
167 you can avoid having to complete at all in many cases, but if you do,
168 you might want to fall into menu selection immediately and to have the
169 words sorted by time:
170 ---------------------------------------------------------------------------------------------------
171 zstyle ':completion:*:*:xdvi:*' menu yes select
172 zstyle ':completion:*:*:xdvi:*' file-sort time
173 ---------------------------------------------------------------------------------------------------
175 Completing process IDs with menu selection:
176 ---------------------------------------------------------------------------------------------------
177 zstyle ':completion:*:*:kill:*' menu yes select
178 zstyle ':completion:*:kill:*' force-list always
179 ---------------------------------------------------------------------------------------------------
181 If you end up using a directory as argument, this will remove the
182 trailing slash (usefull in ln)
183 ---------------------------------------------------------------------------------------------------
184 zstyle ':completion:*' squeeze-slashes true
185 ---------------------------------------------------------------------------------------------------
187 cd will never select the parent directory (e.g.: cd ../<TAB>):
188 ---------------------------------------------------------------------------------------------------
189 zstyle ':completion:*:cd:*' ignore-parents parent pwd
190 ---------------------------------------------------------------------------------------------------
192 UNSORTED/MISC examples
193 ~~~~~~~~~~~~~~~~~~~~~~
194 Hint: A list of valid glob Qualifiers can be found in zshexpn(1).
195 See ``man 1 zshexpn | less -p'' Qualifiers for details.
197 -------------------------------------------------------------------------------
198 # Show me all the .c files for which there doesn't exist a .o file.
199 $ c=(*.c) o=(*.o(N)) eval 'ls ${${c:#(${~${(j:|:)${o:r}}}).c}:?done}'
201 # All files in /var/ that are not owned by root
202 $ ls -ld /var/*(^u:root)
204 # All files for which the owner hat read and execute permissions
207 # The same, but also others dont have execute permissions
208 $ echo *(f:u+rx,o-x:)
210 # brace expansion - example
213 $ print -r -- $^X.$^Y
214 A.+ A.- B.+ B.- C.+ C.-
216 # Fetch the newest file containing the string 'fgractg*.log' in the
217 # filename and contains the string 'ORA-' in it
218 $ file=(fgractg*.log(Nm0om[1]))
219 $ (($#file)) && grep -l ORA- $file
221 $ files=$( find . -name . -o -prune -name 'fgractg*>log' -mtime 0 -print )
222 > if [ -n "$files" ]; then
226 > file=$(ls -td $files | head -1)
227 > grep -l ORA- "$file"
230 # keep specified number of child processes running until entire task finished
231 $ zsh -c 'sleep 1 & sleep 3 & sleep 2& print -rl -- $jobtexts'
233 # Remove zero length and .bak files in a directory
234 $ rm -i *(.L0) *.bak(.)
236 # print out files that dont have extensions
237 $ printf '%s\n' ^?*.*
238 $ printf '%s\n' ^?*.[^.]*(D)
241 # Finding files which does not contain a specific string
242 $ print -rl file* | comm -2 -3 - <(grep -l string file*)'
243 $ for f (file*(N)) grep -q string $f || print -r $f'
245 # Show/Check whether a option is set or not. It works both with $options as
247 $ echo $options[correct]
252 # Count the number of directories on the stack
253 $ print $((${${(z)${(f)"$(dirs -v)"}[-1]}[1]} + 1)) # or
254 $ dirs -v | awk '{n=$1}END{print n+1}'
256 # Matching all files which do not have a dot in filename
259 # Show only the ip-address from ``ifconfig device''
260 # ifconfig from net-tools (Linux)
261 $ print ${${$(LC_ALL=C /sbin/ifconfig eth0)[7]}:gs/addr://}
262 # ifconfig from 4.2BSD {Free,Net,Open}BSD
263 $ print ${$(/sbin/ifconfig tun0)[6]}
265 # Ping all the IP addresses in a couple of class C's or all hosts
267 $ for i in {1..254}; do ping -c 1 192.168.13.$i; done
270 $ while ( [[ $I -le 255 ]] ) ; do ping -1 2 150.150.150.$I; let I++; done
272 $ for i in $(sed 's/#.*//' > /etc/hosts | awk '{print $2}')
274 : echo "Trying $i ... "
276 : echo '============================='
279 # load all available modules at startup
282 $ for md ($module_path) m=($m $md/**/*(*e:'REPLY=${REPLY#$md/}'::r))
285 # Rename all files within a directory such that their names get a numeral
286 # prefix in the default sort order.
287 $ i=1; for j in *; do mv $j $i.$j; ((i++)); done
288 $ i=1; for f in *; do mv $f $(echo $i | \
289 awk '{ printf("%03d", $0)}').$f; ((i++)); done
290 $ integer i=0; for f in *; do mv $f $[i+=1].$f; done
292 # Find (and print) all symbolic links without a target within the current
294 $ $ file **/*(D@) | fgrep broken
295 $ for i in **/*(D@); [[ -f $i || -d $i ]] || echo $i
296 $ echo **/*(@-^./=%p)
299 # List all plain files that do not have extensions listed in `fignore'
300 $ ls **/*~*(${~${(j/|/)fignore}})(.)
301 # see above, but now omit executables
302 $ ls **/*~*(${~${(j/|/)fignore}})(.^*)
304 # Print out files that dont have extensions (require *setopt extendedglob*
305 # and *setopt dotglob*)
306 $ printf '%s\n' ^?*.*
308 # List files in reverse order sorted by name
311 $ print -rl -- *(^on)
313 # Synonymic to ``ps ax | awk '{print $1}'''
314 $ print -l /proc/*/cwd(:h:t:s/self//)
316 # Get the PID of a process (without ``ps'', ``sed'', ``pgrep'', ..
320 > for i in /proc/<->/stat
322 > [[ "$(< $i)" = *\((${(j:|:)~@})\)* ]] && echo $i:h:t
326 # for X in 'n' 'o' 'p' 'q' 'r' 's' 't' 'u' 'v' 'w' 'x' 'y'; do ...
327 $ for (( i = 36#n; i <= 36#y; i++ )); do
328 > print ${$(([##36]i)):l}
330 # or in combination with ``dc''
331 $ print {$((##n))..$((##y))}P\ 10P | dc
333 $ eval print '${$(([##36]'{$((36#n))..$((36#y))}')):l}'
335 # foreach in one line of shell
336 $ for f (*) print -r -- $f
338 # copy a directory recursively without data/files
343 $ find . -type d -exec env d="$dest_root" \
344 sh -c ' exec mkdir -p -- "$d/$1"' '{}' '{}' \;
346 # If `foo=23'', then print with 10 digit with leading '0'.
348 $ print ${(r:10::0:)foo}
350 # find the name of all the files in their home directory that have
351 # more than 20 characters in their file names
352 print -rl $HOME/${(l:20::?:)~:-}*
355 $ print -r -- ${(qq)m} > $nameoffile # save it
356 $ eval "m=($(cat -- $nameoffile)" # or use
357 $ m=("${(@Q)${(z)"$(cat -- $nameoffile)"}}") # to restore it
359 # get a "ls -l" on all the files in the tree that are younger than a
360 # specified age (e.g "ls -l" all the files in the tree that where
361 # modified in the last 2 days)
363 # This will give you a listing 1 file perl line (not à la ls -R).
364 # Think of an easy way to have a "ls -R" style output with
365 # only files newer than 2 day old.
366 $ for d (. ./**/*(/)) {
367 > print -r -- $'\n'${d}:
370 > (($#l)) && ls -ltd -- $l
374 # If you also want directories to be included even if their mtime
375 # is more than 2 days old:
376 $ for d (. ./**/*(/)) {
377 > print -r -- $'\n'${d}:
380 > (($#l)) && ls -ltd -- $l
384 # And if you want only the directories with mtime < 2 days to be listed:
385 $ for d (. ./**/*(N/m-2)) {
386 > print -r -- $'\n'${d}:
389 > (($#l)) && ls -ltd -- $l
397 $ echo ${(l:$COLUMNS::-:)}
398 # and now with colors (require autoload colors ;colors)
399 $ echo "$bg[red]$fg[black]${(l:42::-:)}"
401 # Redirect STDERR to a command like xless without redirecting STDOUT as well.
403 # but this executes the command asynchronously. To do it synchronously:
404 $ { { foo 1>&3 } 2>&1 | xless } 3>&1
406 # Rename all MP3-Files from name with spaces.mp3 to Name With Spaces.mp3
408 > mv $i ${${(C)i}:s/Mp3/mp3/}
411 # Match file names containing only digits and ending with .xml (require
416 # Remove all "non txt" files
419 # Move 200 files from a directory into another
420 $ mv -- *([1,200]) /another/Dir
422 # Convert images (foo.gif => foo.png):
423 $ for i in **/*.gif; convert $i $i:r.png
425 # convert a collection of mp3 files to wave or cdr,
426 # e.g. file.wav -> file.mp3)
427 $ for i (./*.mp3){mpg321 --w - $i > ${i:r}.wav}
429 # Download with LaTeX2HTML created Files (for example the ZSH-Guide):
430 $ for f in http://zsh.sunsite.dk/Guide/zshguide{,{01..08}}.html; do
431 > lynx -source $f >${f:t}
434 # Move all files in dir1 and dir2 that have line counts greater than 10 to
435 # another directory say "/more10"
436 $ mv dir[12]/**/*.cr(-.e{'((`wc -l < $REPLY` > 10))'}) /more10
438 # Make with dpkg a master-list of everyfile that it has installed
439 $ diff <(find / | sort) <(cat /var/lib/dpkg/info/*.list | sort)
441 # Replace this fucking Escape-Sequences:
442 $ autoload colors ; colors
443 $ print "$bg[cyan]$fg[blue]You are a idiot" >> /dev/pts/3
445 # Get ASCII value of a character
446 $ char=N ; print $((#char))
448 # Filename "Erweiterung"
449 # Note: The (N) says to use the nullglob option for this particular
451 $ for i in *.o(N); do
455 # Rename files; i. e. FOO to foo and bar to BAR
456 $ for i in *(.); mv $i ${i:l} # `FOO' to `foo'
457 $ for i in *(.); mv $i ${i:u} # `bar to `BAR'
459 # Show all suid-files in $PATH
460 $ ls -latg ${(s.:.)PATH} | grep '^...s'
462 $ print -l ${^path}/*(Ns,S)
463 # or show only executables with a user given pattern
464 $ print -l ${^path}/*vim*(*N)
466 # gzip files when containing a certain string
467 $ gzip ${(ps:\0:)"$(grep -lZ foobar ./*.txt(.))"}
469 # A small one-liner, that reads from stdin and prints to stdout the first
470 # unique line i. e. does not print lines that have been printed before
471 # (this is similar to the unique command, but unique can only handle
473 $ IFS=$'\n\n'; print -rl -- ${(Oau)${(Oa)$(cat file;echo .)[1,-2]}}
475 # Lists every executable in PATH
476 $ print -l ${^path}/*(-*N)
478 # Match all .c files in all subdirectories, _except_ any SCCS subdirectories?
479 $ ls **/*.c~(*/)#SCCS/*
481 # List all `README' - files case-insensitive with max. one typo
482 $ ls **/*(#ia2)readme
484 # case insensitive checking for variables
485 $ if [[ $OSTYPE == (#i)LINUX*(#I) ]]; then
486 > echo "Penguin on board."
488 > echo "Not a Linux."
490 -------------------------------------------------------------------------------
492 (Recursive) Globbing - Examples
493 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
494 A list of valid glob Qualifiers can be found in zshexpn(1). *Note:*
495 \*\*/ is equivalent to (*/)#! For example:
496 -------------------------------------------------------------------------------
497 $ print (*/)#zsh_us.ps
498 zsh-4.2.3/Doc/zsh_us.ps
500 zsh-4.2.3/Doc/zsh_us.ps
501 -------------------------------------------------------------------------------
503 -------------------------------------------------------------------------------
504 # Search for `README' in all Subdirectories
507 # find directories that contain both "index.php" and "index.html", or in
508 # general, directories that contain more than one file matching "index.*"
509 $ ls **/*(D/e:'[[ -e $REPLY/index.php && -e $REPLY/index.html ]]':)
511 $ ls **/*(D/e:'l=($REPLY/index.*(N)); (( $#l >= 2 ))':)
513 # Find command to search for directory name instead of basename
514 $ print -rl /**/*~^*/path(|/*)
516 $ find / | grep -e /path/ -e '/path$'
518 # Print he path of the directories holding the ten biggest C regular files
519 # in the current directory and subdirectories.
520 $ print -rl -- **/*.c(D.OL[1,10]:h) | sort -u
522 # Find files with size == 0 and send a mail
523 $ files=(**/*(ND.L0m+0m-2))
524 > (( $#files > 0 )) && print -rl -- $files | \
525 mailx -s "empty files" foo@bar.tdl
528 $ chmod 700 **/(.) # Only files
529 $ chmod 700 **/(/) # Only directories
531 # print out all of the files in that directory in 2 columns
532 $ print -rC2 -- ${1:[...]}/*(D:t)
533 # ^- number ob columns
534 # or - if you feel concerned about special characters - use
535 $ list=(${1:[...]}/*(ND:t))
536 $ (($#list)) && print -rC2 -- ${(V)list}
538 # Search all files in /home/*/*-mail/ with a setting ``chmod -s'' flag
539 # (recursive, include dotfiles) remove the setgid/setuid flag and print
541 $ chmod -s /home/*/*-mail(DNs,S) /home/*/*-mail/**/*(DNs,S))
542 # or with a small script
543 $ for file (/home/*/*-mail(DNs,S) /home/*/*-mail/**/*(DNs,S)) {
545 > chmod -s $file && print -r fixed $file
547 # or use ``zargs'' (require autoload zargs) prevent the arg list too
549 $ zargs /home/*/*-mail(DNs,S) /home/*/*-mail/**/*(DNs,S)) -- chmod -s
551 # List files beginning at `foo23' upwards (foo23, foo24, foo25, ..)
554 # get all files that begin with the date strings from June 4 through
556 $ ls -l 200406{04..10}*(N)
557 # or if they are of the form 200406XX (require ``setopt extended_glob''
558 $ ls -l 200306<4-10>.*
560 # remove spaces from filenames
561 $ for a in ./**/*\ *(Dod); do mv $a ${a:h}/${a:t:gs/ /_}; done
563 # Show only all *.c and *.h - Files
566 # Show only all *.c - files and ignore `foo.c'
569 # show data to *really* binary format
570 $ zsh -ec 'while {} {printf %.8x $n;repeat 8 \
571 > {read -ku0 a printf \ %.8d $(([##2]#a))};print;((n+=8))}' < binary
573 # Show only world-readable files
576 # List files in the current directory are not writable by the owner
577 $ print -l ~/*(ND.^w)
579 # find and delete the files which are older than a given parameter
580 # (seconds/minutes/hours)
581 # deletes all regular file in /Dir that are older than 3 hours
582 $ rm -f /Dir/**/*(.mh+3)
583 # deletes all symlinks in /Dir that are older than 3 minutes
584 $ rm -f /Dir/**/*(@mm+3)
585 # deletes all non dirs in /Dir that are older than 30 seconds
586 $ rm -f /Dir/**/*(ms+30^/)
587 # deletes all folders, sub-folders and files older than one hour
588 $ rm ./**/*(.Dmh+1,.DL0)
589 # deletes all files more than 6 hours old
591 # removes all files but the ten newer ones (delete all but last 10
592 # files in a directory)
594 Note: If you get a arg list too long, you use the builtin rm. For
596 $ zmodload zsh/files ; rm -f **/*(mh+6)
597 or use the zargs function:
598 $ autoload zargs ; zargs **/*(mh+6) -- rm -f
600 # A User's Guide to the Z-Shell /5.9: Filename Generation and Pattern
601 # Matching find all files in all subdirectories, searching recursively,
602 # which have a given name, case insensitive, are at least 50 KB large,
603 # no more than a week old and owned by the root user, and allowing up
604 # to a single error in the spelling of the name. In fact, the required
605 # expression looks like this:
606 $ ls **/(#ia1)name(LK+50mw-1u0)
608 # Change the UID from 102 to 666
609 $ chown 666 **/*(u102)
611 # List all files which have not been updated since last 10 hours
612 $ print -rl -- *(Dmh+10^/)
614 # delete only the oldest file in a directory
615 $ rm ./*filename*(Om[1])
617 # Sort the output from `ls -l' by file size
620 # find most recent file in a directory
621 $ setopt dotglob ; print directory/**/*(om[1])
623 # Show only empty files which nor `group' or `world writable'
626 # find - and list - the ten newest files in directories and subdirs
628 $ print -rl -- **/*(Dom[1,10])
630 # Print only 5 lines by "ls" command (like ``ls -laS | head -n 5'')
633 # display the 5-10 last modified files
634 $ print -rl -- /path/to/dir/**/*(D.om[5,10])
636 # find all files without a valid owner
637 $ chmod someuser /**/*(D^u:${(j.:u:.)${(f)"$(</etc/passwd)"}%%:*}:)
639 # find all the empty directories in a tree
640 $ for f in ***/*(/l2); do foo=($f/*(N)); [[ -z $foo ]] && print $f; done
641 # Note:Since Zsh 4.2.1 the glob qualifier F indicates a non-empty directory.
642 # Hence *(F) indicates all subdirectories with entries, *(/^F) means all
643 # subdirectories with no entries.
646 # remove empty directories afterwards
647 $ rmdir ./**/*(/od) 2> /dev/null
649 # Show only files are owned from group `users'
652 -------------------------------------------------------------------------------
656 Modifiers are a powerful mechanism that let you modify the results
657 returned by parameter, filename and history expansion. See zshexpn(1)
659 -------------------------------------------------------------------------------
660 # Remove a trailing pathname component, leaving the head. This works like
665 # Remove all leading pathname components, leaving the tail. This works
670 # Remove the suffix from each file (*.sh in this example)
671 $f:e is $f file extension
672 :h --> head (dirname)
673 :t --> tail (basename)
674 :r --> rest (extension removed)
675 $ for f (*.sh) mv $f $f:r
677 # Remove a filename extension of the form `.xxx', leaving the root name.
683 # Remove all but the extension.
690 # Print the new command but do not execute it. Only works with history
697 # Quote the substituted words, escaping further substitutions.
704 # Convert the words to all lowercase.
711 # Convert the words to all uppercase.
718 # convert 1st char of a word to uppercase
719 $ foo="one two three four"
720 $ print -r -- "${(C)var}"
722 -------------------------------------------------------------------------------
726 See zshmisc(1) for more informations (or less ${^fpath}/zmv(N))
728 -------------------------------------------------------------------------------
729 # Append `exit 1' at the end of all *.sh - files
730 $ echo "exit 1" >> *.sh
732 # adding files to foobar.tar.gz
733 $ eval set =(gunzip < foobar.tar.gz) '
734 tar rf $1 additional.txt &&gzip < $1 > foobar.tar.gz'
736 # Redirect output to a file AND display on screen
737 $ foobar >&1 > file1 > file2 > ..
739 # pipe single output to multiple inputs
740 $ zcat foobar.Z >> (gzip -9 > file1.gz) \
741 >> (bzip2 -9 > file1.bz2) \
742 >> (acb --best > file1.acb)
744 # Append /etc/services at the end of file `foo' and `bar'
745 $ cat /etc/services >> foo >> bar
748 $ echo An error >&2 2>&1 | sed -e 's/A/I/'
750 # send standard output of one process to standard input of several processes
753 $ process1 > >(process1) > >(process2)
755 # initializing a variable and simultaneously keeping terminal output
757 $ { a=$(command >&1 >& 3 3 > &- 2>&1);} 3>&1
759 # redirect stderr two times
760 $ setopt multios ; program 2> file2 > file1 2>&1
762 # Duplicating stdout and stderr to a logfile
763 $ exec 3>&1 > logfile 2>&2 2>&1 >&3 3>&-
765 # redirect stderr (only) to a file and to orig. stderr:
766 $ command 2>&2 2>stderr
767 # redirect stderr and stdout to separate files and both to orig. stdout:
768 $ command 2>&1 1>&1 2>stderr 1>stdout
769 # redirect stderr and stdout to separate files and stdout to orig. stdout
770 # AND stderr to orig. stderr:
771 $ command 2>&2 1>&1 2>stderr 1>stdout
773 # More fun with STDERR ;)
774 $ ./my-script.sh 2> >(grep -v moron >error.log)|process-output >output.log
775 $ echo "Thats STDOUT" >>(sed 's/stdout/another example/' > foobar)
776 -------------------------------------------------------------------------------
778 ZMV-Examples (require autoload zmv)
779 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
780 *Note:* '-n' means no execution (just print what would happen). At
781 -------------------------------------------------------------------------------
782 # serially all files (foo.foo > 1.foo, fnord.foo > 2.foo, ..)
785 1.c asd.foo bla.foo fnord.foo foo.fnord foo.foo
786 $ c=1 zmv '*.foo' '$((c++)).foo'
788 1.c 1.foo 2.foo 3.foo 4.foo foo.fnord
790 # Rename "file.with.many.dots.txt" by substituting dots (exept for the last
792 $ touch {1..20}-file.with.many.dots.txt
793 $ zmv '(*.*)(.*)' '${1//./ }$2'
795 # Remove the first 4 chars from a filename
796 $ zmv -n '*' '$f[5,-1]' # NOTE: The "5" is NOT a mistake in writing!
798 # Rename names of all files under the current Dir to lower case, but keep
800 $ zmv -Qv '(**/)(*)(.D)' '$1${(L)2}'
802 # replace all 4th character, which is "1", with "2" and so on
804 $ zmv '(???)1(???[1-4].txt)' '${1}2${2}'
806 # Remove the first 15 characters from a string
807 $ touch 111111111111111{a-z}
809 $ zmv '*' '$f[16,-1]'
811 # Replace spaces (any number of them) with a single dash in file names
813 $ zmv -n '(**/)(* *)' '$1${2//( #-## #| ##)/-}'
815 $ find . -depth -name '* *' -exec bash -c '
820 > newname=${name//*([ -]) *([ -])/-}
821 > mv -i -- "$file" "$Dir/$newname"' {} {} \;
823 # Clean up file names and remove special characters
825 $ zmv -n '(**/)(*)' '$1${2//[^A-Za-z0-9._]/_}'
827 # Add *.py to a bunch of python scripts in a directory (some of them end
828 # in *.py and give them all a proper extension
830 $ zmv -n '(**/)(con*)(#qe,file $REPLY | grep "python script",)' '$1$2.py'
832 # lowercase all extensions (i. e. *.JPG) incl. subfolders
834 $ zmv '(**/)(*).(#i)jpg' '$1$2.jpg'
836 $ find Dir -name '*.[jJ][pP][gG]' -print | while read f
840 > *) mv "$f" "${f%.*}.jpg" ;
844 # remove leading zeros from file extension
847 filename.001 filename.003 filename.005 filename.007 filename.009
848 filename.002 filename.004 filename.006 filename.008 filename.010
849 $ zmv '(filename.)0##(?*)' '$1$2'
851 filename.1 filename.10 filename.2 filename.3 filename.4 filename.5 ..
856 foo_10.jpg foo_2.jpg foo_3.jpg foo_4.jpg foo_5.jpg foo_6.jpg ..
857 $ zmv -fQ 'foo_(<0->).jpg(.nOn)' 'foo_$(($1 + 1)).jpg'
859 foo_10.jpg foo_11.jpg foo_3.jpg foo_4.jpg foo_5.jpg ...
861 # adding leading zeros to a filename (1.jpg -> 001.jpg, ..
863 $ zmv '(<1->).jpg' '${(l:3::0:)1}.jpg'
865 # See above, but now only files with a filename >= 30 chars
867 $ c=1 zmv "${(l:30-4::?:)}*.foo" '$((c++)).foo'
869 # Replace spaces in filenames with a underline
871 $ zmv '* *' '$f:gs/ /_'
873 # Change the suffix from *.sh to *.pl
875 $ zmv -W '*.sh' '*.pl'
877 # Add a "".txt" extension to all the files within ${HOME}
878 # ``-.'' is to only rename regular files or symlinks to regular files,
879 # ``D'' is to also rename hidden files (dotfiles))
881 $ zmv -Q '/home/**/*(D-.)' '$f.txt'
882 # Or to only rename files that don't have an extension:
883 $ zmv -Q '/home/**/^?*.*(D-.)' '$f.txt'
885 # Recursively change filenames with characters ? [ ] / = + < > ; : " , - *
887 $ chars='[][?=+<>;",*-]'
888 $ zmv '(**/)(*)' '$1${2//$~chars/%}'
890 # Removing single quote from filenames (recursively)
892 $ zmv -Q "(**/)(*'*)(D)" "\$1\${2//'/}"
894 # When a new file arrives (named file.txt) rename all files in order to
895 # get (e. g. file119.txt becomes file120.txt, file118.txt becomes
896 # file119.txt and so on ending with file.txt becoming file1.txt
898 $ zmv -fQ 'file([0-9]##).txt(On)' 'file$(($1 + 1)).txt'
900 # lowercase/uppercase all files/directories
902 $ zmv '(*)' '${(L)1}' # lowercase
903 $ zmv '(*)' '${(U)1}' # uppercase
905 # Remove the suffix *.c from all C-Files
909 # Uppercase only the first letter of all *.mp3 - files
911 $ zmv '([a-z])(*).mp3' '${(C)1}$2.mp3'
913 # Copy the target `README' in same directory as each `Makefile'
915 $ zmv -C '(**/)Makefile' '${1}README'
917 # Removing single quote from filenames (recursively)
919 $ zmv -Q "(**/)(*'*)(D)" "\$1\${2//'/}"
921 # Rename pic1.jpg, pic2.jpg, .. to pic0001.jpg, pic0002.jpg, ..
923 $ zmv 'pic(*).jpg' 'pic${(l:4::0:)1}.jpg'
924 $ zmv '(**/)pic(*).jpg' '$1/pic${(l:4::0:)2}.jpg' # recursively
925 -------------------------------------------------------------------------------
929 Please read zshmodules(1) first!
931 zsh/pcre (require zmodload zsh/pcre)
932 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
934 -------------------------------------------------------------------------------
935 # Copy files of a certain period (date indicated in the filenames)
937 $ ls -d -- *(e:'[[ $REPLY -pcre-match pcre-regexp ]]':)
939 $ m() { [[ $1 -pcre-match pcre-regexp ]] }
941 -------------------------------------------------------------------------------
943 zsh/clone (require zmodload zsh/clone)
944 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
945 -------------------------------------------------------------------------------
946 # Creates a forked instance of the current shell ($! is set to zero) and
947 # execute ``command'' on /dev/tty8 (for this example).
949 $ clone /dev/tty8 && (($! == 0)) && exec command
950 -------------------------------------------------------------------------------
952 zsh/datetime (require zmodload zsh/datetime)
953 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
954 -------------------------------------------------------------------------------
955 $ zmodload zsh/datetime
956 $ alias datereplacement='strftime "%Y-%m-%d" $EPOCHSECONDS'
957 $ export DATE=`datereplacement`
960 # strip date from filename
961 $ $ zmodload zsh/datetime
962 $ setopt extendedglob
963 $ touch aaa_bbb_20041212_c.dat eee_fff_20051019_g.dat
964 $ strftime -s pattern \
965 '???_???_<0-%Y%m%d>_?.dat' $((EPOCHSECONDS - 365 * 24 * 60 * 60 / 2))
966 $ print -rl -- $~pattern
967 aaa_bbb_20041212_c.dat
968 $ print -rl -- $pattern
969 ???_???_<0-20050815>_?.dat
971 # Search files size == 0, to be based on the file name containing a date
972 # rather than the "last modified" date of the file
973 $ zmodload -i zsh/datetime
974 $ strftime -s file "abc_de_%m%d%Y.dat" $((EPOCHSECONDS - 24 * 60 * 60 ))
975 $ files=(**/$file(N.L0))
976 $ (( $#files > 0 )) && print -rl -- $files | \
977 mailx -s "empty files" foo@bar.tdl
978 -------------------------------------------------------------------------------
980 zsh/stat (require zmodload zsh/stat)
981 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
982 -------------------------------------------------------------------------------
983 # comparing file dates
987 $ touch bar & sleep 5 & touch foo
988 $ echo $file1 is $(($(stat +mtime $file2) - \
989 $(stat +mtime $file1))) seconds older than $file2.
990 bar is 5 seconds older than foo
992 # list the files of a disk smaller than some other file
994 $ stat -A max +size some-other-file
995 $ print -rl ./**/*(D.L-$max)
997 # List the top 100 biggest files in a disk
999 $ ls -fld ./**/*(d`stat +device .`OL[1,100])
1001 # Get only the user name and the file names from (like
1002 # ls -l * | awk '{print $3" " $8}')
1005 > stat -sA user +uid -- "$file" &&
1006 > print -r -- "$user" "$file"
1009 # get the difference between actual bytes of file and allocated bytes of file
1011 $ print $(($(stat +block -- file) * 512 - $(stat +size -- file)))
1014 # ``D'' : to include dot files (d lowercase is for device)
1015 # ``O'' : reverse Ordered (o lowercase for non-reverse order)
1016 # ``L'' : by file Length (l is for number of links)
1017 # ``[1]'': return only first one
1019 $ stat +size ./*(DOL[1])
1021 # file size in bytes
1023 $ stat -L +size ~/.zshrc
1026 # Delete files in a directory that hasn't been accessed in the last ten days
1027 # and send ONE mail to the owner of the files informing him/her of the files'
1029 $ zmodload zsh/stat zsh/files
1030 $ typeset -A f; f=()
1031 $ rm -f /path/**/*(.a+10e{'stat -sA u +uidr $REPLY; f[$u]="$f[$u]$REPLY"'})
1032 $ for user (${(k)f}) {print -rn $f[$user]|mailx -s "..." $user}
1034 # Get a "ls -l" on all the files in the tree that are younger than a
1037 $ for d (. ./**/*(N/m-2))
1038 > print -r -- $'\n'$d: && cd $d && {
1040 > stat -F '%b %d %H:%M' -LsAs -- $f &&
1041 > print -r -- $s[3] ${(l:4:)s[4]} ${(l:8:)s[5]} \
1042 > ${(l:8:)s[6]} ${(l:8:)s[8]} $s[10] $f ${s[14]:+-> $s[14]}
1046 # get file creation date
1048 $ stat -F '%d %m %Y' +mtime ~/.zshrc
1050 $ stat -F '%D' +mtime ~/.zshrc
1052 -------------------------------------------------------------------------------
1054 zsh/files (require zmodload zsh/files)
1055 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1056 -------------------------------------------------------------------------------
1057 # search a directory for files containing a certain string then copy those
1058 # files to another directory.
1059 $ zmodload zsh/files
1061 $ cp $(grep -lZr foobar .) otherdirectory
1062 -------------------------------------------------------------------------------
1064 zsh/mapfile (require zmodload zsh/mapfile)
1065 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1066 -------------------------------------------------------------------------------
1067 # grepping for two patterns
1068 $ zmodload zsh/mapfile
1070 $ pattern2="bar foo"
1071 $ print -l ./**/*(DN.e{'z=$mapfile[$REPLY] && [[ $z = *$pattern1* && \
1072 $z = *$pattern2* ]]'})
1073 # or a solution in combination with zsh/pcre
1074 $ zmodload -i zsh/mapfile zsh/pcre
1076 $ pattern2="bar foo"
1077 $ pcre_compile "(?s)(?=.*?$pattern1).*?$pattern2"
1079 $ print -l ./**/*(DN.e{'pcre_match $mapfile[$REPLY]'})
1081 # equivalent for ``less /etc/passwd | grep -v root''
1082 $ zmodload zsh/mapfile
1084 $ print -rl -- ${${=mapfile[/etc/passwd]}:#*root*}
1085 # or - for case insensitive
1086 $ setopt extendedglob
1087 $ print -rl -- ${${=mapfile[/etc/passwd]}:#*(#i)root*}
1089 # If a XML-file contains stuff like ``<TAGA/>'' and ``<TAGB/>'', number
1090 # this empty tags (ones ending in '/>') so if encountered in the same
1091 # order, the preceeding tags would become ``<TAGA/>1</TAGA>'' and
1092 # ``<TAGB/>2</TAGB>''
1093 $ zmodload zsh/mapfile
1095 $ apfile[data.xml.new]=${(S)mapfile[data.xml]//\
1096 > (#im)<TAGA>*<\/TAGA>/<TAGA>$((++cnt))<\/TAGA>}
1098 # removing all files in users Maildir/new that contain ``filename="gone.src''
1099 $ zmodload zsh/{files,mapfile}
1100 $ rm -f /u1/??/*/Maildir/new/100*(.e{'[[ $mapfile[$REPLY] == \
1101 *filename=\"gone.scr\"* ]]'})
1103 # Grep out the Title from a postscript file and append that value to the
1104 # end of the filename
1106 $ zmodload zsh/mapfile
1107 $ zmv '(*).ps' '$1-${${${mapfile[$f]##*%%Title: }%% *}//[^a-zA-Z0-9_]/}.ps'
1108 -------------------------------------------------------------------------------
1110 zsh/mathfunc (require zmodload zsh/mathfunc)
1111 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1112 -------------------------------------------------------------------------------
1113 $ zmodload zsh/mathfunc
1114 $ echo $(( sin(1/4.0)**2 + cos(1/4.0)**2 - 1 ))
1115 -1.1102230246251565e-16
1116 $ echo $(( pi = 4.0 * atan(1.0) ))
1118 $ echo $(( f = sin(0.3) ))
1120 $ print $((1e12 * rand48()))
1122 $ print $(( rand48(seed) ))
1124 -------------------------------------------------------------------------------
1126 zsh/termcap (require zmodload zsh/termcap)
1127 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1128 -------------------------------------------------------------------------------
1129 $ zmodload -ab zsh/termcap echotc
1130 $ GREEN=`echotc AF 2`
1131 $ YELLOW=`echotc AF 3`
1133 $ BRIGHTRED=`echotc md ; echotc AF 1`
1134 $ print -l ${GREEN}green ${YELLOW}yellow ${RED}red ${BRIGHTRED}brightred
1135 -------------------------------------------------------------------------------
1137 zsh/zpty (require zmodload zsh/zpty)
1138 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1139 -------------------------------------------------------------------------------
1143 # ``-r'': read the output of the command name.
1145 $ zpty -r PW z '*password:'
1146 # send the to command name the given strings as input
1148 $ zpty -r PW z '*password:'
1150 # The second form, with the -d option, is used to delete commands
1151 # previously started, by supplying a list of their names. If no names
1152 # are given, all commands are deleted. Deleting a command causes the HUP
1153 # signal to be sent to the corresponding process.
1155 -------------------------------------------------------------------------------
1157 zsh/net/socket (require zmodload zsh/net/socket)
1158 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1159 -------------------------------------------------------------------------------
1160 # ``-l'': open a socket listening on filename
1161 # ``-d'': argument will be taken as the target file descriptor for the
1163 # ``3'' : file descriptor. See ``A User's Guide to the Z-Shell''
1164 # (3.7.2: File descriptors)
1165 $ zmodload zsh/net/socket
1167 # ``-a'': accept an incoming connection to the socket
1169 $ zsocket -a -d 5 3 # accept a connection
1173 -------------------------------------------------------------------------------
1175 zsh/zftp (require zmodload zsh/zftp)
1176 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1177 -------------------------------------------------------------------------------
1178 $ autoload -U zfinit
1180 $ zfparams www.example.invalid myuserid mypassword
1183 $ zfls -l zshtips.html
1184 $ zfput zshtips.html
1185 $ zfls -l zshtips.html
1187 # Automatically transfer files using FTP with error checking
1188 $ autoload -U zfinit ; zfinit
1189 $ zftp open host.name.invalid user passwd || exit
1190 $ zftp get /remote/file > /local/file; r=$?
1191 $ zftp close && exit r
1193 # compress and ftp on the fly
1194 $ autoload -U zfinit ; zfinit
1195 $ zftp open host.name.invalid user password
1196 $ zftp get $file | bzip2 > ${file}.bz2
1200 $ autoload -U zfinit ; zfinit
1203 $ for file in `zfls` ; do
1208 # Upload all regular files in $HOME/foobar (recursive) that are newer than
1209 # two hours to ftp.foobar.invalid/path/to/upload
1210 $ autoload -U zfinit ; zfinit
1211 $ zfopen ftp.foobar.invalid/path/to/upload
1213 $ zfput -r **/*(.mh-2)
1216 # long list of files on a ftp
1217 $ autoload -U zfinit ; zfinit
1219 $ zfcd /some/remote/Dir
1220 $ cd /some/local/Dir
1221 # If the list.txt is located on the remote host, change to
1222 # zfget ${(f)"$(zftp get /path/to/remote/list.txt)"}
1223 $ zfget ${(f)"$(cat list.txt)"}
1225 -------------------------------------------------------------------------------
1227 zsh/zselect (require zmodload zsh/zselect)
1228 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1229 -------------------------------------------------------------------------------
1233 | $ stty -icanon min 0 time 50
1236 | $ case "$yesno" in
1241 $ zmodload zsh/zselect
1242 $ if zselect -t 500 -r 0 && read yesno && [ yes = "$yesno" ]; then
1247 ------------------------------------------------------------------------------
1253 *auto_cd* (allow one to change to a directory by entering it as a
1254 command). *auto_pushd* (automatically append dirs to the push/pop list)
1255 pushd_ignore_dups (and don't duplicate them).
1259 *no_hup* (don't send HUP signal to background jobs when exiting ZSH).
1260 *print_exit_value* (show a message with the exit code when a command
1261 returns with a non-zero exit code)
1265 *hist_verify* (let the user edit the command line after history
1266 expansion (e.g. !ls) instead of immediately running it) +
1267 Use the same history file for all sessions : +
1268 *setopt SHARE_HISTORY*
1272 *no_clobber* (or set -C; prevent '>' redirection from truncating
1273 the given file if it already exists)
1277 *correct* (automatically correct the spelling of commands).
1278 *correct_all* (automatically correct the spelling of each word on the
1279 command line) *dvorak* (dvorak layout)
1283 Mailpath: simple multiple mailpath:
1284 -----------------------------------------------------
1285 mailpath=($HOME/Mail/mbox'?new mail in mbox'
1286 $HOME/Mail/tux.u-strasbg'?new mail in tux'
1287 $HOME/Mail/lilo'?new mail in lilo'
1288 $HOME/Mail/ldap-fr'?new mail in ldap-fr')
1289 -----------------------------------------------------
1291 Mailpath: dynamic mailpath:
1292 -----------------------------------------------------
1294 for i in ~/Mail/Lists/*(.); do
1295 mailpath[$#mailpath+1]="${i}?You have new mail in ${i:t}."
1297 -----------------------------------------------------
1298 Avoid globbing on special commands:
1299 --------------------------------------------------------
1300 for com in alias expr find mattrib mcopy mdir mdel which;
1301 alias $com="noglob $com"
1302 --------------------------------------------------------
1304 For migrating your bashprompt to zsh use the script bash2zshprompt located in
1305 the zsh source distribution under 'Misc'.
1307 For migration from (t)csh to zsh use the c2z tool that converts csh
1308 aliases and environment and shell variables to zsh. It does this by running
1309 csh, and having csh report on aliases and variables. The script then converts
1310 these to zsh startup files. It has some issues and usage information that are
1311 documented at the top of this script.
1313 Here are functions to set the title and hardstatus of an *XTerm* or of *GNU
1314 Screen* to 'zsh' and the current directory, respectively, when the prompt is
1315 displayed, and to the command name and rest of the command line, respectively,
1316 when a command is executed:
1317 ------------------------------------------------------------------
1319 if [[ $TERM == "screen" ]]; then
1320 # Use these two for GNU Screen:
1321 print -nR $' 33k'$1$' 33'\
1322 print -nR $' 33]0;'$2$''
1323 elif [[ $TERM == "xterm" || $TERM == "rxvt" ]]; then
1324 # Use this one instead for XTerms:
1325 print -nR $' 33]0;'$*$''
1328 function precmd { title zsh "$PWD" }
1331 local -a cmd; cmd=(${(z)1})
1332 title $cmd[1]:t "$cmd[2,-1]"
1334 ------------------------------------------------------------------
1336 Put the following line into your ~/.screenrc to see this fancy hardstatus:
1337 -----------------------------------------
1338 caption always "%3n %t%? (%u)%?%?: %h%?"
1339 -----------------------------------------
1342 Special variables which are assigned:
1343 ------------------------------------------------------
1344 $LINENO $RANDOM $SECONDS $COLUMNS $HISTCHARS $UID
1345 $EUID $GID $EGID $USERNAME $fignore $mailpath $cdpath
1346 ------------------------------------------------------
1351 *http://www.zsh.org/[]*
1353 *http://sourceforge.net/projects/zsh/[]*
1354 Z shell page at sunsite.dk::
1355 *http://zsh.sunsite.dk/[]*
1356 From Bash to Z Shell: Conquering the Command Line - the book::
1357 *http://www.bash2zsh.com/[]*
1358 Mailinglistarchive::
1359 *http://www.zsh.org/mla/[]*
1361 *http://www.zsh.org/FAQ/[]*
1363 *http://zsh.sunsite.dk/Guide/[]*
1365 *http://www.zshwiki.org/[]*
1366 Die Zsh als interaktive Shell::
1367 *http://cssun.rrze.uni-erlangen.de/~sipakale/zshreferat.html[]*
1368 A short introduction from BYU::
1369 *http://docs.cs.byu.edu/docs/zsh/index.php[]*
1371 *http://stchaz.free.fr/mouse.zsh[]*
1372 Shell Corner: Zsh Suite of "keeper" Functions::
1373 *http://www.unixreview.com/documents/s=9513/ur0501a/ur0501a.htm[]*
1374 The Z Shell (A Fan Page)::
1375 *http://www.princeton.edu/~kmccarty/zsh.html[]*
1376 Making the Transition to Zsh::
1377 *http://www.linux-mag.com/cgi-bin/printer.pl?issue=2002-05&article=power[]*
1378 Curtains up: introducing the Z shell::
1379 *http://www-128.ibm.com/developerworks/linux/library/l-z.html?dwzone=linux[]*
1380 ZSH-Liebhaberseite::
1381 *http://michael-prokop.at/computer/tools_zsh_liebhaber.html[]*
1382 ZSH-Seite von Michael Prokop::
1383 *http://www.michael-prokop.at/computer/tools_zsh.html[]*
1384 A Case for the Z Shell on *http://www.daemonnews.org/[]*::
1385 *http://ezine.daemonnews.org/199910/zsh.html[]*
1386 ZSH-Section from Dotfiles.com::
1387 *http://www.dotfiles.com/index.php?app_id=4[]*
1388 Writing Zsh Completion Functions::
1389 *http://www.linux-mag.com/2002-07/power_01.html[]*
1390 ZSH Prompt introduction::
1391 *http://aperiodic.net/phil/prompt/[]*
1393 *http://www.adamspiers.org/computing/zsh/[]*
1394 Zzappers Best of ZSH Tips::
1395 *http://www.rayninfo.co.uk/tips/zshtips.html[]*
1396 Zsh Webpage by Christian Schneider::
1397 *http://strcat.de/zsh/[]*
1398 The zsh-lovers webpage::
1399 *http://grml.org/zsh/[]*
1401 *#zsh at irc.freenode.org*
1402 The Z shell reference-card (included in the zsh-lovers debian-package)::
1403 *http://www.bash2zsh.com/zsh_refcard/refcard.pdf[]*
1407 This manpage was written by Michael Prokop, Christian 'strcat'
1408 Schneider and Matthias Kopfermann. But many ideas have been taken from
1409 zsh-geeks e.g. from the zsh-mailinglists (zsh-users and zsh-workers),
1410 google, newsgroups and the zsh-Wiki. +
1411 Thanks for your cool and incredible tips. We learned much from you!
1413 In alphabetic order:
1414 -------------------------------------------------------------------------
1415 Andrew 'zefram' Main - http://www.fysh.org/~zefram/
1416 Barton E. Schaefer - http://www.well.com/user/barts/
1417 Matthias Kopfermann - http://www.infodrom.north.de/~matthi/
1418 Oliver Kiddle - http://people.freenet.de/opk/
1419 Paul Falstad - http://www.falstad.com/
1420 Peter Stephenson - http://python.swan.ac.uk/~pypeters/
1422 Stephane Chazelas - http://stephane.chazelas.free.fr/
1423 Sven Guckes - http://www.guckes.net/
1424 Sven Wischnowsky - http://w9y.de/zsh/zshrc
1425 -------------------------------------------------------------------------
1430 ------------------------------------------------------------------
1431 zsh Zsh overview (this section)
1432 zshmisc Anything not fitting into the other sections
1433 zshexpn Zsh command and parameter expansion
1434 zshparam Zsh parameters
1435 zshoptions Zsh options
1436 zshbuiltins Zsh built-in functions
1437 zshzle Zsh command line editing
1438 zshcompwid Zsh completion widgets
1439 zshcompsys Zsh completion system
1440 zshcompctl Zsh completion control
1441 zshmodules Zsh loadable modules
1442 zshzftpsys Zsh built-in FTP client
1443 zshall Meta-man page containing all of the above
1444 ------------------------------------------------------------------
1446 Note: especially 'man zshcontrib' covers very useful topics! +
1447 Book: *From Bash to Z Shell* by Oliver Kiddle, Jerry Peck and Peter
1448 Stephenson. *ISBN: 1590593766*. - *http://www.bash2zsh.com/[bash2zsh.com]* +
1449 Also take a look at the section *LINKS* in this manpage.
1453 Probably. This manpage might be never complete. So please report bugs,
1454 feedback and suggestions to <zsh-lovers@michael-prokop.at>. Thank
1459 Copyright \(C) Michael Prokop, Christian Schneider and Matthias