home *** CD-ROM | disk | FTP | other *** search
Text File | 1993-02-19 | 55.6 KB | 2,439 lines |
- Newsgroups: comp.sources.misc
- From: zsh-list@cs.uow.edu.au (The Zsh Mailing List)
- Subject: v35i053: zsh - The Z Shell, version 2.3.1, Part03/22
- Message-ID: <1993Feb20.212032.28166@sparky.imd.sterling.com>
- X-Md4-Signature: cbf11e1334e0785c3220a1644257cb50
- Date: Sat, 20 Feb 1993 21:20:32 GMT
- Approved: kent@sparky.imd.sterling.com
-
- Submitted-by: zsh-list@cs.uow.edu.au (The Zsh Mailing List)
- Posting-number: Volume 35, Issue 53
- Archive-name: zsh/part03
- Environment: UNIX
- Supersedes: zsh2.2: Volume 29, Issue 97-113
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then feed it
- # into a shell via "sh file" or similar. To overwrite existing files,
- # type "sh file -c".
- # The tool that generated this appeared in the comp.sources.unix newsgroup;
- # send mail to comp-sources-unix@uunet.uu.net if you want that tool.
- # Contents: doc/intro.txt.01 help/autoload src/Makefile.sample
- # Wrapped by mattson@odin on Sat Feb 6 14:41:51 1993
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- echo If this archive is complete, you will see the following message:
- echo ' "shar: End of archive 3 (of 22)."'
- if test -f 'doc/intro.txt.01' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'doc/intro.txt.01'\"
- else
- echo shar: Extracting \"'doc/intro.txt.01'\" \(49646 characters\)
- sed "s/^X//" >'doc/intro.txt.01' <<'END_OF_FILE'
- X
- X
- X
- X
- X
- X
- X An Introduction to the Z Shell
- X
- X
- X Paul Falstad
- X pf@ttisms.com
- X
- X
- X
- X
- X
- X
- Xzsh is a shell designed for interactive use, although it is
- Xalso a powerful scripting language. Many of the useful
- Xfeatures of bash, ksh, and tcsh were incorporated into zsh;
- Xmany original features were added. This document details
- Xsome of the unique features of zsh. It assumes basic
- Xknowledge of the standard UNIX shells; the intent is to show
- Xa reader already familiar with one of the other major shells
- Xwhat makes zsh more useful or more powerful. This document
- Xis not at all comprehensive; read the manual entry for a
- Xdescription of the shell that is complete and concise,
- Xalthough somewhat overwhelming and devoid of examples.
- X
- XFilename Generation
- X
- XOtherwise known as globbing, filename generation is quite
- Xextensive in zsh. Of course, it has all the basics:
- X
- X% ls
- XMakefile file.pro foo.o main.o q.c run234 stuff
- Xbar.o foo link morestuff run123 run240 sub
- Xfile.h foo.c main.h pipe run2 run303
- X% ls *.c
- Xfoo.c q.c
- X% ls *.[co]
- Xbar.o foo.c foo.o main.o q.c
- X% ls foo.?
- Xfoo.c foo.o
- X% ls *.[^c]
- Xbar.o file.h foo.o main.h main.o
- X% ls *.[^oh]
- Xfoo.c q.c
- X
- X
- XAlso, if the EXTENDEDGLOB option is set, some new features
- Xare activated. For example, the ^ character negates the
- Xpattern following it:
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X - 2 -
- X
- X% setopt extendedglob
- X% ls -d ^*.c
- XMakefile file.pro link morestuff run2 run303
- Xbar.o foo main.h pipe run234 stuff
- Xfile.h foo.o main.o run123 run240 sub
- X% ls -d ^*.*
- XMakefile link pipe run2 run240 stuff
- Xfoo morestuff run123 run234 run303 sub
- X% ls -d ^Makefile
- Xbar.o foo link morestuff run123 run240 sub
- Xfile.h foo.c main.h pipe run2 run303
- Xfile.pro foo.o main.o q.c run234 stuff
- X% ls -d *.^c
- X.rhosts bar.o file.h file.pro foo.o main.h main.o
- X
- X
- XAn expression of the form <x-y> matches a range of integers:
- X
- X% ls run<200-300>
- Xrun234 run240
- X% ls run<300-400>
- Xrun303
- X% ls run<-200>
- Xrun123 run2
- X% ls run<300->
- Xrun303
- X% ls run<>
- Xrun123 run2 run234 run240 run303
- X
- X
- XGrouping is possible:
- X
- X% ls (foo|bar).*
- Xbar.o foo.c foo.o
- X% ls *.(c|o|pro)
- Xbar.o file.pro foo.c foo.o main.o q.c
- X
- X
- XAlso, the string **/ forces a recursive search of sub-
- Xdirectories:
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X - 3 -
- X
- X% ls -R
- XMakefile file.pro foo.o main.o q.c run234 stuff
- Xbar.o foo link morestuff run123 run240 sub
- Xfile.h foo.c main.h pipe run2 run303
- X
- Xmorestuff:
- X
- Xstuff:
- Xfile xxx yyy
- X
- Xstuff/xxx:
- Xfoobar
- X
- Xstuff/yyy:
- Xfrobar
- X% ls **/*bar
- Xstuff/xxx/foobar stuff/yyy/frobar
- X% ls **/f*
- Xfile.h foo foo.o stuff/xxx/foobar
- Xfile.pro foo.c stuff/file stuff/yyy/frobar
- X% ls *bar*
- Xbar.o
- X% ls **/*bar*
- Xbar.o stuff/xxx/foobar stuff/yyy/frobar
- X% ls stuff/**/*bar*
- Xstuff/xxx/foobar stuff/yyy/frobar
- X
- X
- X
- XIt is possible to exclude certain files from the patterns
- Xusing the ~ character. A pattern of the form *.c~bar.c
- Xlists all files matching *.c, except for the file bar.c.
- X
- X% ls *.c
- Xfoo.c foob.c bar.c
- X% ls *.c~bar.c
- Xfoo.c foob.c
- X% ls *.c~f*
- Xbar.c
- X
- X
- X
- XOne can add a number of qualifiers to the end of any of
- Xthese patterns, to restrict matches to certain file types.
- XA qualified pattern is of the form
- X
- X pattern(...)
- X
- X
- Xwith single-letter qualifiers inside the parentheses.
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X - 4 -
- X
- X% alias l='ls -dF'
- X% l *
- XMakefile foo* main.h q.c run240
- Xbar.o foo.c main.o run123 run303
- Xfile.h foo.o morestuff/ run2 stuff/
- Xfile.pro link@ pipe run234 sub
- X% l *(/)
- Xmorestuff/ stuff/
- X% l *(@)
- Xlink@
- X% l *(*)
- Xfoo* link@ morestuff/ stuff/
- X% l *(x)
- Xfoo* link@ morestuff/ stuff/
- X% l *(X)
- Xfoo* link@ morestuff/ stuff/
- X% l *(R)
- Xbar.o foo* link@ morestuff/ run123 run240
- Xfile.h foo.c main.h pipe run2 run303
- Xfile.pro foo.o main.o q.c run234 stuff/
- X
- X
- XNote that *(x) and *(*) both match executables. *(X)
- Xmatches files executable by others, as opposed to *(x),
- Xwhich matches files executable by the owner. *(R) and *(r)
- Xmatch readable files; *(W) and *(w), which checks for writ-
- Xable files. *(W) is especially important, since it checks
- Xfor world-writable files:
- X
- X% l *(w)
- Xbar.o foo* link@ morestuff/ run123 run240
- Xfile.h foo.c main.h pipe run2 run303
- Xfile.pro foo.o main.o q.c run234 stuff/
- X% l *(W)
- Xlink@ run240
- X% l -l link run240
- Xlrwxrwxrwx 1 pfalstad 10 May 23 18:12 link -> /bin/false*
- X-rw-rw-rw- 1 pfalstad 0 May 23 18:12 run240
- X
- X
- XYou can filter out the symbolic links with the ^ character:
- X
- X% l *(W^@)
- Xrun240
- X% l *(x)
- Xfoo* link@ morestuff/ stuff/
- X% l *(x^@/)
- Xfoo*
- X
- X
- XTo find all plain files, you can use .:
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X - 5 -
- X
- X% l *(.)
- XMakefile file.h foo* foo.o main.o run123 run234 run303
- Xbar.o file.pro foo.c main.h q.c run2 run240 sub
- X% l *(^.)
- Xlink@ morestuff/ pipe stuff/
- X% l s*(.)
- Xstuff/ sub
- X% l *(p)
- Xpipe
- X% l -l *(p)
- Xprw-r--r-- 1 pfalstad 0 May 23 18:12 pipe
- X
- X
- X*(U) matches all files owned by you. To search for all
- Xfiles not owned by you, use *(^U):
- X
- X% l -l *(^U)
- X-rw------- 1 subbarao 29 May 23 18:13 sub
- X
- X
- XThis searches for setuid files:
- X
- X% l -l *(s)
- X-rwsr-xr-x 1 pfalstad 16 May 23 18:12 foo*
- X
- X
- XThis checks for a certain user's files:
- X
- X% ypmatch subbarao passwd
- Xsubbarao:*:3338:35:Kartik Subbarao:/u/subbarao:/usr/princeton/bin/zsh
- X% l -l *(u3338)
- X-rw------- 1 subbarao 29 May 23 18:13 sub
- X
- X
- X
- XStartup Files
- X
- XThere are five startup files that zsh will read commands
- Xfrom:
- X
- X$ZDOTDIR/.zshenv
- X$ZDOTDIR/.zprofile
- X$ZDOTDIR/.zshrc
- X$ZDOTDIR/.zlogin
- X$ZDOTDIR/.zlogout
- X
- X
- XIf ZDOTDIR is not set, then the value of HOME is used; this
- Xis the usual case.
- X
- X.zshenv is sourced on all invocations of the shell, unless
- Xthe -f option is set. It should contain commands to set the
- Xcommand search path, plus other important environment vari-
- Xables. .zshenv should not contain commands that produce
- Xoutput or assume the shell is attached to a tty.
- X
- X.zshrc is sourced in interactive shells. It should contain
- Xcommands to set up aliases, functions, options, key bind-
- Xings, etc.
- X
- X
- X
- X
- X
- X - 6 -
- X.zlogin is sourced in login shells. It should contain com-
- Xmands that should be executed only in login shells. .zlo-
- Xgout is sourced when login shells exit. .zprofile is simi-
- Xlar to .zlogin, except that it is sourced before .zshrc.
- X.zprofile is meant as an alternative to .zlogin for ksh
- Xfans; the two are not intended to be used together, although
- Xthis could certainly be done if desired. .zlogin is not the
- Xplace for alias definitions, options, environment variable
- Xsettings, etc.; as a general rule, it should not change the
- Xshell environment at all. Rather, it should be used to set
- Xthe terminal type and run a series of external commands
- X(fortune, msgs, etc).
- X
- XShell Functions
- X
- Xzsh also allows you to create your own commands by defining
- Xshell functions. For example:
- X
- X% yp () {
- X> ypmatch $1 passwd.byname
- X> }
- X% yp pfalstad
- Xpfalstad:*:3564:35:Paul John Falstad:/u/pfalstad:/usr/princeton/bin/zsh
- X
- X
- XThis function looks up a user in the NIS password map. The
- X$1 expands to the first argument to yp. The function could
- Xhave been equivalently defined in one of the following ways:
- X
- X% function yp {
- X> ypmatch $1 passwd.byname
- X> }
- X% function yp () {
- X> ypmatch $1 passwd.byname
- X> }
- X% function yp () ypmatch $1 passwd.byname
- X
- X
- XNote that aliases are expanded when the function definition
- Xis parsed, not when the function is executed. For example:
- X
- X% alias ypmatch=echo
- X% yp pfalstad
- Xpfalstad:*:3564:35:Paul John Falstad:/u/pfalstad:/usr/princeton/bin/zsh
- X
- X
- XSince the alias was defined after the function was parsed,
- Xit has no effect on the function's execution. However, if
- Xwe define the function again with the alias in place:
- X
- X% function yp () { ypmatch $1 passwd.byname }
- X% yp pfalstad
- Xpfalstad passwd.byname
- X
- X
- Xit is parsed with the new alias definition in place. There-
- Xfore, in general you must define aliases before functions.
- X
- XWe can make the function take multiple arguments:
- X
- X
- X
- X
- X
- X
- X - 7 -
- X
- X% unalias ypmatch
- X% yp () {
- X> for i
- X> do ypmatch $i passwd.byname
- X> done
- X> }
- X% yp pfalstad subbarao sukthnkr
- Xpfalstad:*:3564:35:Paul John Falstad:/u/pfalstad:/usr/princeton/bin/zsh
- Xsubbarao:*:3338:35:Kartik Subbarao:/u/subbarao:/usr/princeton/bin/zsh
- Xsukthnkr:*:1267:35:Rahul Sukthankar:/u/sukthnkr:/usr/princeton/bin/tcsh
- X
- X
- XThe for i loops through each of the function's arguments,
- Xsetting i equal to each of them in turn. We can also make
- Xthe function do something sensible if no arguments are
- Xgiven:
- X
- X% yp () {
- X> if (( $# == 0 ))
- X> then echo usage: yp name ...; fi
- X> for i; do ypmatch $i passwd.byname; done
- X> }
- X% yp
- Xusage: yp name ...
- X% yp pfalstad sukthnkr
- Xpfalstad:*:3564:35:Paul John Falstad:/u/pfalstad:/usr/princeton/bin/zsh
- Xsukthnkr:*:1267:35:Rahul Sukthankar:/u/sukthnkr:/usr/princeton/bin/tcsh
- X
- X
- X$# is the number of arguments supplied to the function. If
- Xit is equal to zero, we print a usage message; otherwise, we
- Xloop through the arguments, and ypmatch all of them.
- X
- XHere's a function that selects a random line from a file:
- X
- X% randline () {
- X> integer z=$(wc -l <$1)
- X> sed -n $[RANDOM % z + 1]p $1
- X> }
- X% randline /etc/motd
- XPHOENIX WILL BE DOWN briefly Friday morning, 5/24/91 from 8 AM to
- X% randline /etc/motd
- XSunOS Release 4.1.1 (PHOENIX) #19: Tue May 14 19:03:15 EDT 1991
- X% randline /etc/motd
- X| Please use the "msgs" command to read announcements. Refer to the |
- X% echo $z
- X
- X%
- X
- X
- Xrandline has a local variable, z, that holds the number of
- Xlines in the file. $[RANDOM % z + 1] expands to a random
- Xnumber between 1 and z. An expression of the form $[...]
- Xexpands to the value of the arithmetic expression within the
- Xbrackets, and the RANDOM variable returns a random number
- Xeach time it is referenced. % is the modulus operator, as
- Xin C. Therefore, sed -n $[RANDOM%z+1]p picks a random line
- Xfrom its input, from 1 to z.
- X
- X
- X
- X
- X
- X
- X - 8 -
- XFunction definitions can be viewed with the functions buil-
- Xtin:
- X
- X% functions randline
- Xrandline () {
- X integer z=$(wc -l <$1)
- X sed -n $[RANDOM % z + 1]p $1
- X
- X}
- X% functions
- Xyp () {
- X if let $# == 0
- X
- X then
- X echo usage: yp name ...
- X
- X fi
- X for i
- X do
- X ypmatch $i passwd.byname
- X
- X done
- X
- X}
- Xrandline () {
- X integer z=$(wc -l <$1)
- X sed -n $[RANDOM % z + 1]p $1
- X
- X}
- X
- X
- XHere's another one:
- X
- X% cx () { chmod +x $* }
- X% ls -l foo bar
- X-rw-r--r-- 1 pfalstad 29 May 24 04:38 bar
- X-rw-r--r-- 1 pfalstad 29 May 24 04:38 foo
- X% cx foo bar
- X% ls -l foo bar
- X-rwxr-xr-x 1 pfalstad 29 May 24 04:38 bar
- X-rwxr-xr-x 1 pfalstad 29 May 24 04:38 foo
- X
- X
- XNote that this could also have been implemented as an alias:
- X
- X% chmod 644 foo bar
- X% alias cx='chmod +x'
- X% cx foo bar
- X% ls -l foo bar
- X-rwxr-xr-x 1 pfalstad 29 May 24 04:38 bar
- X-rwxr-xr-x 1 pfalstad 29 May 24 04:38 foo
- X
- X
- X
- XInstead of defining a lot of functions in your .zshrc, all
- Xof which you may not use, it is often better to use the
- Xautoload builtin. The idea is, you create a directory where
- Xfunction definitions are stored, declare the names in your
- X.zshrc, and tell the shell where to look for them. Whenever
- Xyou reference a function, the shell will automatically load
- X
- X
- X
- X
- X
- X - 9 -
- Xit into memory.
- X
- X% mkdir /tmp/funs
- X% cat >/tmp/funs/yp
- Xypmatch $1 passwd.byname
- X^D
- X% cat >/tmp/funs/cx
- Xchmod +x $*
- X^D
- X% FPATH=/tmp/funs
- X% autoload cx yp
- X% functions cx yp
- Xundefined cx ()
- Xundefined yp ()
- X% chmod 755 /tmp/funs/{cx,yp}
- X% yp egsirer
- Xegsirer:*:3214:35:Emin Gun Sirer:/u/egsirer:/bin/sh
- X% functions yp
- Xyp () {
- X ypmatch $1 passwd.byname
- X}
- X
- X
- XThis idea has other benefits. By adding a #! header to the
- Xfiles, you can make them double as shell scripts. (Although
- Xit is faster to use them as functions, since a separate pro-
- Xcess is not created.)
- X
- X% ed /tmp/funs/yp
- X25
- Xi
- X#! /usr/local/bin/zsh
- Xw
- X42
- Xq
- X% </tmp/funs/yp
- X#! /usr/local/bin/zsh
- Xypmatch $1 passwd.byname
- X% /tmp/funs/yp sukthnkr
- Xsukthnkr:*:1267:35:Rahul Sukthankar:/u/sukthnkr:/usr/princeton/bin/tcsh
- X
- X
- XNow other people, who may not use zsh, or who don't want to
- Xcopy all of your .zshrc, may use these functions as shell
- Xscripts.
- X
- XDirectories
- X
- XOne nice feature of zsh is the way it prints directories.
- XFor example, if we set the prompt like this:
- X
- Xphoenix% PROMPT='%~> '
- X~> cd src
- X~/src>
- X
- X
- Xthe shell will print the current directory in the prompt,
- Xusing the ~ character. However, zsh is smarter than most
- Xother shells in this respect:
- X
- X
- X
- X
- X
- X
- X - 10 -
- X
- X~/src> cd ~subbarao
- X~subbarao> cd ~maruchck
- X~maruchck> cd lib
- X~maruchck/lib> cd fun
- X~maruchck/lib/fun> foo=/usr/princeton/common/src
- X~maruchck/lib/fun> cd ~foo
- X~foo> cd ..
- X/usr/princeton/common> cd src
- X~foo> cd news/nntp
- X~foo/news/nntp> cd inews
- X~foo/news/nntp/inews>
- X
- X
- XNote that zsh prints other users' directories in the form
- X~user. Also note that you can set a parameter and use it as
- Xa directory name; zsh will act as if foo is a user with the
- Xlogin directory /usr/princeton/common/src. This is con-
- Xvenient, especially if you're sick of seeing prompts like
- Xthis:
- X
- Xphoenix:/usr/princeton/common/src/X.V11R4/contrib/clients/xv/docs>
- X
- X
- XIf you get stuck in this position, you can give the current
- Xdirectory a short name, like this:
- X
- X/usr/princeton/common/src/news/nntp/inews> inews=$PWD
- X/usr/princeton/common/src/news/nntp/inews> echo ~inews
- X/usr/princeton/common/src/news/nntp/inews
- X~inews>
- X
- X
- XWhen you reference a directory in the form ~inews, the shell
- Xassumes that you want the directory displayed in this form;
- Xthus simply typing echo ~inews or cd ~inews causes the
- Xprompt to be shortened. You can define a shell function for
- Xthis purpose:
- X
- X~inews> namedir () { $1=$PWD ; : ~$1 }
- X~inews> cd /usr/princeton/bin
- X/usr/princeton/bin> namedir pbin
- X~pbin> cd /var/spool/mail
- X/var/spool/mail> namedir spool
- X~spool> cd .msgs
- X~spool/.msgs>
- X
- X
- XYou may want to add this one-line function to your .zshrc.
- X
- Xzsh can also put the current directory in your title bar, if
- Xyou are using a windowing system. One way to do this is
- Xwith the chpwd function, which is automatically executed by
- Xthe shell whenever you change directory. If you are using
- Xxterm, this will work:
- X
- Xchpwd () { print -Pn '^[]2;%~^G' }
- X
- X
- XThe -P option tells print to treat its arguments like a
- X
- X
- X
- X
- X
- X - 11 -
- Xprompt string; otherwise the %~ would not be expanded. The
- X-n option suppresses the terminating newline, as with echo.
- X
- XIf you are using an IRIS wsh, do this:
- X
- Xchpwd () { print -Pn '^[P1.y%~^[' }
- X
- X
- XThe print -D command has other uses. For example, to print
- Xthe current directory to standard output in short form, you
- Xcan do this:
- X
- X% print -D $PWD
- X~subbarao/src
- X
- X
- Xand to print each component of the path in short form:
- X
- X% print -D $path
- X/bin /usr/bin ~locbin ~locbin/X11 ~/bin
- X
- X
- X
- XDirectory Stacks
- X
- XIf you use csh, you may know about directory stacks. The
- Xpushd command puts the current directory on the stack, and
- Xchanges to a new directory; the popd command pops a direc-
- Xtory off the stack and changes to it.
- X
- Xphoenix% cd
- Xphoenix% PROMPT='Z %~> '
- XZ ~> pushd /tmp
- X/tmp ~
- XZ /tmp> pushd /usr/etc
- X/usr/etc /tmp ~
- XZ /usr/etc> pushd /usr/bin
- X/usr/bin /usr/etc /tmp ~
- XZ /usr/bin> popd
- X/usr/etc /tmp ~
- XZ /usr/etc> popd
- X/tmp ~
- XZ /tmp> pushd /etc
- X/etc /tmp ~
- XZ /etc> popd
- X/tmp ~
- X
- X
- Xzsh's directory stack commands work similarly. One differ-
- Xence is the way pushd is handled if no arguments are given.
- XAs in csh, this exchanges the top two elements of the direc-
- Xtory stack:
- X
- XZ /tmp> dirs
- X/tmp ~
- XZ /tmp> pushd
- X~ /tmp
- X
- X
- Xunless the stack only has one entry:
- X
- X
- X
- X
- X
- X - 12 -
- X
- XZ ~> popd
- X/tmp
- XZ /tmp> dirs
- X/tmp
- XZ /tmp> pushd
- X~ /tmp
- X
- X
- Xor unless the PUSHDTOHOME option is set:
- X
- XZ ~> setopt pushdtohome
- XZ ~> pushd
- X~ ~ /tmp
- X
- X
- X
- XAs an alternative to using directory stacks in this manner,
- Xwe can get something like a directory history by setting a
- Xfew more options and parameters:
- X
- X~> DIRSTACKSIZE=8
- X~> setopt autopushd pushdminus pushdsilent pushdtohome
- X~> alias dh='dirs -v'
- X~> cd /tmp
- X/tmp> cd /usr
- X/usr> cd bin
- X/usr/bin> cd ../pub
- X/usr/pub> dh
- X0 /usr/pub
- X1 /usr/bin
- X2 /usr
- X3 /tmp
- X4 ~
- X/usr/pub> cd -3
- X/tmp> dh
- X0 /tmp
- X1 /usr/pub
- X2 /usr/bin
- X3 /usr
- X4 ~
- X/tmp> ls =2/df
- X/usr/bin/df
- X/tmp> cd -4
- X~>
- X
- X
- XNote that =2 expanded to the second directory in the history
- Xlist, and that cd -3 recalled the third directory in the
- Xlist.
- X
- XYou may be wondering what all those options do. AUTOPUSHD
- Xmade cd act like pushd. (alias cd=pushd is not sufficient,
- Xfor various reasons.) PUSHDMINUS swapped the meaning of cd
- X+1 and cd -1; we want them to mean the opposite of what they
- Xmean in csh, because it makes more sense in this scheme, and
- Xit's easier to type:
- X
- X
- X
- X
- X
- X
- X
- X
- X - 13 -
- X
- X~> dh
- X0 ~
- X1 /tmp
- X2 /usr/pub
- X3 /usr/bin
- X4 /usr
- X~> unsetopt pushdminus
- X~> cd +1
- X/tmp> dh
- X0 /tmp
- X1 ~
- X2 /usr/pub
- X3 /usr/bin
- X4 /usr
- X/tmp> cd +2
- X/usr/pub>
- X
- X
- XPUSHDSILENT keeps the shell from printing the directory
- Xstack each time we do a cd, and PUSHDTOHOME we mentioned
- Xearlier:
- X
- X/usr/pub> unsetopt pushdsilent
- X/usr/pub> cd /etc
- X/etc /usr/pub /tmp ~ /usr/bin /usr
- X/etc> cd
- X~ /etc /usr/pub /tmp ~ /usr/bin /usr
- X~> unsetopt pushdtohome
- X~> cd
- X/etc ~ /usr/pub /tmp ~ /usr/bin /usr
- X/etc>
- X
- X
- XDIRSTACKSIZE keeps the directory stack from getting too
- Xlarge, much like HISTSIZE:
- X
- X/etc> setopt pushdsilent
- X/etc> cd /
- X/> cd /
- X/> cd /
- X/> cd /
- X/> cd /
- X/> cd /
- X/> cd /
- X/> cd /
- X/> dh
- X0 /
- X1 /
- X2 /
- X3 /
- X4 /
- X5 /
- X6 /
- X7 /
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X - 14 -
- XCommand/Process Substitution
- X
- XCommand substitution in zsh can take two forms. In the
- Xtraditional form, a command enclosed in backquotes (`...`)
- Xis replaced on the command line with its output. This is
- Xthe form used by the older shells. Newer shells (like zsh)
- Xalso provide another form, $(...). This form is much easier
- Xto nest.
- X
- X% ls -l `echo /vmunix`
- X-rwxr-xr-x 1 root 1209702 May 14 19:04 /vmunix
- X% ls -l $(echo /vmunix)
- X-rwxr-xr-x 1 root 1209702 May 14 19:04 /vmunix
- X% who | grep mad
- Xsubbarao ttyt7 May 23 15:02 (mad55sx15.Prince)
- Xpfalstad ttyu1 May 23 16:25 (mad55sx14.Prince)
- Xsubbarao ttyu6 May 23 15:04 (mad55sx15.Prince)
- Xpfalstad ttyv3 May 23 16:25 (mad55sx14.Prince)
- X% who | grep mad | awk '{print $2}'
- Xttyt7
- Xttyu1
- Xttyu6
- Xttyv3
- X% cd /dev; ls -l $(who |
- X> grep $(echo mad) |
- X> awk '{ print $2 }')
- Xcrwx-w---- 1 subbarao 20, 71 May 23 18:35 ttyt7
- Xcrw--w---- 1 pfalstad 20, 81 May 23 18:42 ttyu1
- Xcrwx-w---- 1 subbarao 20, 86 May 23 18:38 ttyu6
- Xcrw--w---- 1 pfalstad 20, 99 May 23 18:41 ttyv3
- X
- X
- XMany common uses of command substitution, however, are
- Xsuperseded by other mechanisms of zsh:
- X
- X% ls -l `tty`
- Xcrw-rw-rw- 1 root 20, 28 May 23 18:35 /dev/ttyqc
- X% ls -l $TTY
- Xcrw-rw-rw- 1 root 20, 28 May 23 18:35 /dev/ttyqc
- X% ls -l `which rn`
- X-rwxr-xr-x 1 root 172032 Mar 6 18:40 /usr/princeton/bin/rn
- X% ls -l =rn
- X-rwxr-xr-x 1 root 172032 Mar 6 18:40 /usr/princeton/bin/rn
- X
- X
- XA command name with a = prepended is replaced with its full
- Xpathname. This can be very convenient. If it's not con-
- Xvenient for you, you can turn it off:
- X
- X% ls
- X=foo =bar
- X% ls =foo =bar
- Xzsh: foo not found
- X% setopt noequals
- X% ls =foo =bar
- X=foo =bar
- X
- X
- X
- XAnother nice feature is process substitution:
- X
- X
- X
- X
- X
- X - 15 -
- X
- X% who | fgrep -f =(print -l root lemke shgchan subbarao)
- Xroot console May 19 10:41
- Xlemke ttyq0 May 22 10:05 (narnia:0.0)
- Xlemke ttyr7 May 22 10:05 (narnia:0.0)
- Xlemke ttyrd May 22 10:05 (narnia:0.0)
- Xshgchan ttys1 May 23 16:52 (gaudi.Princeton.)
- Xsubbarao ttyt7 May 23 15:02 (mad55sx15.Prince)
- Xsubbarao ttyu6 May 23 15:04 (mad55sx15.Prince)
- Xshgchan ttyvb May 23 16:51 (gaudi.Princeton.)
- X
- X
- XA command of the form =(...) is replaced with the name of a
- Xfile containing its output. (A command substitution, on the
- Xother hand, is replaced with the output itself.) print -l is
- Xlike echo, excepts that it prints its arguments one per
- Xline, the way fgrep expects them:
- X
- X% print -l foo bar
- Xfoo
- Xbar
- X
- X
- XWe could also have written:
- X
- X% who | fgrep -f =(echo 'root
- X> lemke
- X> shgchan
- X> subbarao')
- X
- X
- XUsing process substitution, you can edit the output of a
- Xcommand:
- X
- X% ed =(who | fgrep -f ~/.friends)
- X355
- Xg/lemke/d
- Xw /tmp/filbar
- X226
- Xq
- X% cat /tmp/filbar
- Xroot console May 19 10:41
- Xshgchan ttys1 May 23 16:52 (gaudi.Princeton.)
- Xsubbarao ttyt7 May 23 15:02 (mad55sx15.Prince)
- Xsubbarao ttyu6 May 23 15:04 (mad55sx15.Prince)
- Xshgchan ttyvb May 23 16:51 (gaudi.Princeton.)
- X
- X
- Xor easily read archived mail:
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X - 16 -
- X
- X% mail -f =(zcat ~/mail/oldzshmail.Z)
- X"/tmp/zsha06024": 84 messages, 0 new, 43 unread
- X> 1 U TO: pfalstad, zsh (10)
- X 2 U nytim!tim@uunet.uu.net, Re: Zsh on Sparc1 /SunOS 4.0.3
- X 3 U JAM%TPN@utrcgw.utc.com, zsh fix (15)
- X 4 U djm@eng.umd.edu, way to find out if running zsh? (25)
- X 5 U djm@eng.umd.edu, Re: way to find out if running zsh? (17)
- X 6 r djm@eng.umd.edu, Meta . (18)
- X 7 U jack@cs.glasgow.ac.uk, Re: problem building zsh (147)
- X 8 U nytim!tim@uunet.uu.net, Re: Zsh on Sparc1 /SunOS 4.0.3
- X 9 ursa!jmd, Another fix... (61)
- X 10 U pplacewa@bbn.com, Re: v18i084: Zsh 2.00 - A small complaint (36)
- X 11 U lubkin@cs.rochester.edu, POSIX job control (34)
- X 12 U yale!bronson!tan@uunet.UU.NET
- X 13 U brett@rpi.edu, zsh (36)
- X 14 S subbarao, zsh sucks!!!! (286)
- X 15 U snibru!d241s008!d241s013!ala@relay.EU.net, zsh (165)
- X 16 U nytim!tim@uunet.UU.NET, Re: Zsh on Sparc1 /SunOS 4.0.3
- X 17 U subbarao, zsh is a junk shell (43)
- X 18 U amaranth@vela.acs.oakland.edu, zsh (33)
- X43u/84 1: x
- X% ls -l /tmp/zsha06024
- X/tmp/zsha06024 not found
- X
- X
- XNote that the shell creates a temporary file, and deletes it
- Xwhen the command is finished.
- X
- X% diff =(ls) =(ls -F)
- X3c3
- X< fortune
- X---
- X> fortune*
- X10c10
- X< strfile
- X---
- X> strfile*
- X
- X
- XIf you read zsh's man page, you may notice that <(...) is
- Xanother form of process substitution which is similar to
- X=(...). There is an important difference between the two.
- XIn the <(...) case, the shell creates a named pipe (FIFO)
- Xinstead of a file. This is better, since it does not fill
- Xup the file system; but it does not work in all cases. In
- Xfact, if we had replaced =(...) with <(...) in the examples
- Xabove, all of them would have stopped working except for
- Xfgrep -f <(...). You can not edit a pipe, or open it as a
- Xmail folder; fgrep, however, has no problem with reading a
- Xlist of words from a pipe. You may wonder why diff <(foo)
- Xbar doesn't work, since foo | diff - bar works; this is
- Xbecause diff creates a temporary file if it notices that one
- Xof its arguments is -, and then copies its standard input to
- Xthe temporary file.
- X
- XAliasing
- X
- XOften-used commands can be abbreviated with an alias:
- X
- X
- X
- X
- X
- X
- X - 17 -
- X
- X% alias uc=uncompress
- X% ls
- Xhanoi.Z
- X% uc hanoi
- X% ls
- Xhanoi
- X
- X
- Xor commands with certain desired options:
- X
- X% alias fm='finger -m'
- X% fm root
- XLogin name: root In real life: Operator
- XDirectory: / Shell: /bin/csh
- XOn since May 19 10:41:15 on console 3 days 5 hours Idle Time
- XNo unread mail
- XNo Plan.
- X
- X% alias lock='lock -p -60000'
- X% lock
- Xlock: /dev/ttyr4 on phoenix. timeout in 60000 minutes
- Xtime now is Fri May 24 04:23:18 EDT 1991
- XKey:
- X
- X% alias l='ls -AF'
- X% l /
- X.bash_history kadb*
- X.bashrc lib@
- X.cshrc licensed/
- X.exrc lost+found/
- X.login macsyma
- X
- X
- XAliases can also be used to replace old commands:
- X
- X% alias grep=egrep ps=sps make=gmake
- X% alias whoami='echo root'
- X% whoami
- Xroot
- X
- X
- Xor to define new ones:
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X - 18 -
- X
- X% cd /
- X% alias sz='ls -l | sort -n +3 | tail -10'
- X% sz
- Xdrwxr-sr-x 7 bin 3072 May 23 11:59 etc
- Xdrwxrwxrwx 26 root 5120 May 24 04:20 tmp
- Xdrwxr-xr-x 2 root 8192 Dec 26 19:34 lost+found
- Xdrwxr-sr-x 2 bin 14848 May 23 18:48 dev
- X-r--r--r-- 1 root 140520 Dec 26 20:08 boot
- X-rwxr-xr-x 1 root 311172 Dec 26 20:08 kadb
- X-rwxr-xr-x 1 root 1209695 Apr 16 15:33 vmunix.old
- X-rwxr-xr-x 1 root 1209702 May 14 19:04 vmunix
- X-rwxr-xr-x 1 root 1209758 May 21 12:23 vmunix.new.kernelmap.old
- X-rwxr-xr-x 1 root 1711848 Dec 26 20:08 vmunix.org
- X% cd
- X% alias rable='ls -AFtrd *(R)' nrable='ls -AFtrd *(^R)'
- X% rable
- XREADME func/ bin/ pub/ News/ src/
- Xnicecolors etc/ scr/ tmp/ iris/ zsh*
- X% nrable
- XMailboxes/ mail/ notes
- X
- X
- X(The pattern *(R) matches all readable files in the current
- Xdirectory, and *(^R) matches all unreadable files.)
- X
- XMost other shells have aliases of this kind (command
- Xaliases). However, zsh also has global aliases, which are
- Xsubstituted anywhere on a line. Global aliases can be used
- Xto abbreviate frequently-typed usernames, hostnames, etc.
- X
- X% alias -g me=pfalstad gun=egsirer mjm=maruchck
- X% who | grep me
- Xpfalstad ttyp0 May 24 03:39 (mickey.Princeton)
- Xpfalstad ttyp5 May 24 03:42 (mickey.Princeton)
- X% fm gun
- XLogin name: egsirer In real life: Emin Gun Sirer
- XDirectory: /u/egsirer Shell: /bin/sh
- XLast login Thu May 23 19:05 on ttyq3 from bow.Princeton.ED
- XNew mail received Fri May 24 02:30:28 1991;
- X unread since Fri May 24 02:30:27 1991
- X% alias -g phx=phoenix.princeton.edu warc=wuarchive.wustl.edu
- X% ftp warc
- XConnected to wuarchive.wustl.edu.
- X
- X
- XHere are some more interesting uses.
- X
- X% alias -g M='| more' GF='| fgrep -f ~/.friends'
- X% who M # pipes the output of who through more
- X% who GF # see if your friends are on
- X% w GF # see what your friends are doing
- X
- X
- XAnother example makes use of zsh's process substitution. If
- Xyou run NIS, and you miss being able to do this:
- X
- X% grep pfalstad /etc/passwd
- X
- X
- X
- X
- X
- X
- X
- X - 19 -
- Xyou can define an alias that will seem more natural than
- Xypmatch pfalstad passwd:
- X
- X% alias -g PASS='<(ypcat passwd)'
- X% grep pfalstad PASS
- Xpfalstad:*:3564:35:Paul John Falstad:/u/pfalstad:/usr/princeton/bin/zsh
- X
- X
- XIf you're really crazy, you can even call it /etc/passwd:
- X
- X% alias -g /etc/passwd='<(ypcat passwd)'
- X% grep pfalstad /etc/passwd
- Xpfalstad:*:3564:35:Paul John Falstad:/u/pfalstad:/usr/princeton/bin/zsh
- X
- X
- XThe last example shows one of the perils of global aliases;
- Xthey have a lot of potential to cause confusion. For exam-
- Xple, if you defined a global alias called | (which is possi-
- Xble), zsh would begin to act very strangely; every pipe sym-
- Xbol would be replaced with the text of your alias. To some
- Xextent, global aliases are like macros in C; discretion is
- Xadvised in using them and in choosing names for them. Using
- Xnames in all caps is not a bad idea, especially for aliases
- Xwhich introduce shell metasyntax (like M and GF above).
- X
- XNote that zsh aliases are not like csh aliases. The syntax
- Xfor defining them is different, and they do not have argu-
- Xments. All your favorite csh aliases will probably not work
- Xunder zsh. For example, if you try:
- X
- Xalias rm mv '\!* /tmp/wastebasket'
- X
- X
- Xno aliases will be defined, but zsh will not report an
- Xerror. In csh, this line defines an alias that makes rm
- Xsafe---files that are rm'd will be moved to a temporary
- Xdirectory instead of instantly destroyed. In zsh's syntax,
- Xhowever, this line asks the shell to print any existing
- Xalias definitions for rm, mv, or !* /tmp/wastebasket. Since
- Xthere are none, most likely, the shell will not print any-
- Xthing, although alias will return a nonzero exit code. The
- Xproper syntax is this:
- X
- Xalias rm='mv \!* /tmp/wastebasket'
- X
- X
- XHowever, this won't work either:
- X
- X% rm foo.dvi
- Xzsh: no matches found: !*
- X
- X
- XWhile this makes rm safe, it is certainly not what the user
- Xintended. In zsh, you must use a shell function for this:
- X
- X% unalias rm
- X% rm () { mv $* /tmp/wastebasket }
- X% rm foo.dvi
- X% ls /tmp/wastebasket
- Xfoo.dvi
- X
- X
- X
- X
- X
- X - 20 -
- XWhile this is much cleaner and easier to read (I hope you
- Xwill agree), it is not csh-compatible. Therefore, a script
- Xto convert csh aliases and variables has been provided. You
- Xshould only need to use it once, to convert all your csh
- Xaliases and parameters to zsh format:
- X
- X% csh
- Xcsh> alias
- Xl ls -AF
- Xmore less
- Xon last -2 !:1 ; who | grep !:1
- Xcsh> exit
- X% c2z >neat_zsh_aliases
- X% cat neat_zsh_aliases
- Xalias l='ls -AF'
- Xalias more='less'
- Xon () { last -2 $1 ; who | grep $1 }
- X...
- X
- X
- XThe first two aliases were converted to regular zsh aliases,
- Xwhile the third, since it needed to handle arguments, was
- Xconverted to a function. c2z can convert most aliases to
- Xzsh format without any problems. However, if you're using
- Xsome really arcane csh tricks, or if you have an alias with
- Xa name like do (which is reserved in zsh), you may have to
- Xfix some of the aliases by hand.
- X
- XThe c2z script checks your csh setup, and produces a list of
- Xzsh commands which replicate your aliases and parameter set-
- Xtings as closely as possible. You could include its output
- Xin your startup file, .zshrc.
- X
- XHistory
- X
- XThere are several ways to manipulate history in zsh. One
- Xway is to use csh-style ! history:
- X
- X% /usr/local/bin/!:0 !-2*:s/foo/bar/ >>!$
- X
- X
- XIf you don't want to use this, you can turn it off by typing
- Xsetopt nobanghist.
- X
- XAnother way is to use the fc command. For example, if you
- Xtype an erroneous command:
- X
- X% for i in `cat /etc/clients`
- X do
- X rpu $i
- X done
- Xzsh: command not found: rpu
- Xzsh: command not found: rpu
- Xzsh: command not found: rpu
- X
- X
- Xtyping fc will execute an editor on this command, allowing
- Xyou to fix it. (The default editor is vi, by the way, not
- Xed).
- X
- X
- X
- X
- X
- X
- X - 21 -
- X
- X% fc
- X49
- X/rpu/s//rup/p
- X rup $i
- Xw
- X49
- Xq
- Xfor i in `cat /etc/clients`
- X do
- X rup $i
- X done
- X beam up 2 days, 10:17, load average: 0.86, 0.80, 0.50
- X bow up 4 days, 8:41, load average: 0.91, 0.80, 0.50
- X burn up 17:18, load average: 0.91, 0.80, 0.50
- X burst up 9 days, 1:49, load average: 0.95, 0.80, 0.50
- X tan up 11:14, load average: 0.91, 0.80, 0.50
- X bathe up 3 days, 17:49, load average: 1.84, 1.79, 1.50
- X bird up 1 day, 9:13, load average: 1.95, 1.82, 1.51
- X bonnet up 2 days, 21:18, load average: 0.93, 0.80, 0.50
- X
- X
- XA variant of the fc command is r, which redoes the last com-
- Xmand, with optional changes:
- X
- X% echo foo
- Xfoo
- X% r
- Xecho foo
- Xfoo
- X
- X% echo foo
- Xfoo
- X% r foo=bar
- Xecho bar
- Xbar
- X
- X
- X
- XCommand Line Editing
- X
- Xzsh's command line editor, ZLE, is quite powerful. It is
- Xdesigned to emulate either emacs or vi; the default is
- Xemacs. To set the bindings for vi mode, type bindkey -v.
- X
- XIn addition to basic editing, the shell allows you to recall
- Xprevious lines in the history. In emacs mode, this is done
- Xwith ^P (control-P):
- X
- X% ls ~
- X- README file mail pub tmp
- XMailboxes bin func nicecolors scr zsh
- XNews etc iris notes src
- X% echo foobar
- Xfoobar
- X% ^P
- X% echo foobar^P
- X% ls ~_
- X
- X
- X
- X
- X
- X
- X
- X - 22 -
- XPressing ^P once brings up the previous line (echo foobar);
- Xpressing it again brings up the line before that (ls ~).
- XThe cursor is left at the end of the line, allowing you to
- Xedit the line if desired before executing it. In many
- Xcases, ZLE eliminates the need for the fc command, since it
- Xis powerful enough to handle even multiline commands:
- X
- X% for i in a b c d e
- X> do
- X> echo $i
- X> done
- Xa
- Xb
- Xc
- Xd
- Xe
- X% ^P
- X% for i in a b c d e
- X do
- X echo $i
- X done_
- X
- X
- XNow you can just move up to the part you want to change...
- X
- X% for i in _ b c d e
- X do
- X echo $i
- X done
- X
- X
- Xchange it, and execute the new command.
- X
- X% for i in f g h i j
- X do
- X echo $i
- X done
- Xf
- Xg
- Xh
- Xi
- Xj
- X
- X
- XAlso, you can search the history for a certain command using
- XESC-P:
- X
- X% set ESC-P
- X% setopt autolist ESC-P
- X% setopt nocorrect_
- X
- X
- XAnother way is to do an incremental search, emacs-style:
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X - 23 -
- X
- X% ^R
- X% _
- Xi-search:
- X
- X% l_ /usr/bin
- Xi-search: l
- X
- X% date > foofile_c
- Xi-search: le
- X
- X
- XAnother useful feature of the editor is command and filename
- Xcompletion.
- X
- X% compTAB
- X% compress _
- X
- X% ls /nicTAB
- X% ls /nicecolors _
- X
- X% ls /usr/prTAB
- X% ls /usr/princeton/_
- X
- X% ls -l =comTAB
- X% ls -l =compress _
- X
- X
- XIf the completion is ambiguous, the editor will beep. You
- Xcan list possible completions by pressing ^D:
- X
- X% ls /vmuTAB -beep-
- X% ls /vmunix_
- X% ls /vmunix^D
- Xvmunix vmunix.old
- Xvmunix.new.kernelmap.old vmunix.org
- X
- X
- XOr, you could just set the AUTOLIST option:
- X
- X% setopt autolist
- X% ls /vmuTAB -beep-
- Xvmunix vmunix.old
- Xvmunix.new.kernelmap.old vmunix.org
- X% ls /vmunix_
- X
- X
- XAnother option you could set is RECEXACT, which causes exact
- Xmatches to be accepted, even if there are other possible
- Xcompletions:
- X
- X% setopt recexact
- X% ls /vmuTAB -beep-
- Xvmunix vmunix.old
- Xvmunix.new.kernelmap.old vmunix.org
- X% ls /vmunix_TAB
- X% ls /vmunix _
- X
- X
- XThe fignore variable lists suffixes of files to ignore
- X
- X
- X
- X
- X
- X - 24 -
- Xduring completion.
- X
- X% ls fooTAB -beep-
- Xfoofile.c foofile.o
- X% fignore=( .o \~ .bak .junk )
- X% ls fooTAB
- X% ls foofile.c _
- X
- X
- XSince foofile.o has a suffix that is in the fignore list, it
- Xwas not considered a possible completion of foo.
- X
- XUsername completion is also supported:
- X
- X% ls ~pfalTAB
- X% ls ~pfalstad/_
- X
- X
- Xand parameter name completion:
- X
- X% echo $ORGTAB
- X% echo $ORGANIZATION _
- X
- X
- Xand hostname completion, if you give the shell a list of
- Xhosts to complete:
- X
- X% hosts=( phoenix.princeton.edu uunet.uu.net nic.ddn.mil
- X> diskfarm.princeton.edu gnu.ai.mit.edu
- X> eniac.seas.upenn.edu )
- X% telnet diskTAB
- X% telnet diskfarm.princeton.edu _
- X
- X% ftp uuTAB
- X% ftp uunet.uu.net _
- X
- X% mail subbarao@phTAB
- X% mail subbarao@phoenix.princeton.edu _
- X
- X
- Xand option completion:
- X
- X% setopt noclTAB
- X% setopt noclobber _
- X
- X
- Xand binding completion:
- X
- X% bindkey '^X^X' puTAB
- X% bindkey '^X^X' push-line _
- X
- X
- X
- XThe compctl command is used to control how completion works.
- XFor example, to specify that certain commands show take com-
- Xmands as arguments, you use compctl -c:
- X
- X% compctl -c man nohup
- X% man uptTAB
- X% man uptime _
- X
- X
- X
- X
- X
- X - 25 -
- XTo specify that a command should complete filenames, you
- Xshould use compctl -f. This is the default. It can be com-
- Xbined with -c, as well.
- X
- X% compctl -cf echo
- X% echo uptTAB
- X% echo uptime _
- X
- X% echo foTAB
- X% echo foo.c
- X
- X
- XSimilarly, use -h to specify hostnames, -o to specify
- Xoptions, -v to specify variables, and -b to specify bind-
- Xings.
- X
- X% compctl -h rlogin
- X% compctl -hfc rsh
- X% compctl -b bindkey
- X
- X
- XYou can also use -k to specify a custom list of keywords to
- Xuse in completion.
- X
- X% ftphosts=(ftp.uu.net wuarchive.wustl.edu)
- X% compctl -k ftphosts ftp
- X% ftp wuTAB
- X% ftp wuarchive.wustl.edu _
- X
- X% friends=(cpirazzi subbarao sukthnkr)
- X% compctl -k friends mail finger su
- X% finger cpTAB
- X% finger cpirazzi _
- X
- X
- X
- XIn addition to completion, TAB performs expansion if possi-
- Xble.
- X
- X% ls *.cTAB
- X% ls foofile.c fortune.c rnd.c strfile.c unstr.c_
- X
- X
- XFor example, suppose you have a bunch of weird files in an
- Ximportant directory:
- X
- X% ls
- X * * * ; & % $??foo dspfok foo.c
- X !"foo"! ` \ ` foo rrr
- X
- X
- XYou want to remove them, but you don't want to damage foo.c.
- XHere is one way to do this:
- X
- X% rm *TAB
- X% rm \ \ \*\ \*\ \*\ \ \ \!\"foo\"\! \;\ \&\ %\ \$'
- X'foo \`\ \\\ \` dspfok foo foo.c rrr_
- X
- X
- XWhen you expand *, zsh inserts the names of all the files
- X
- X
- X
- X
- X
- X - 26 -
- Xinto the editing buffer, with proper shell quoting. Now,
- Xjust move back and remove foo.c from the buffer:
- X
- X% rm \ \ \*\ \*\ \*\ \ \ \!\"foo\"\! \;\ \&\ %\ \$'
- X'foo \`\ \\\ \` dspfok foo _rr
- X
- X
- Xand press return. Everything except foo.c will be deleted
- Xfrom the directory.
- X
- XHere's another trick; let's say you have typed this command
- Xin:
- X
- X% gcc -o x.out foob.c -g -Wpointer-arith -Wtrigraphs_
- X
- X
- Xand you forget which library you want. You need to escape
- Xout for a minute and check by typing ls /usr/lib, or some
- Xother such command; but you don't want to retype the whole
- Xcommand again, and you can't press return now because the
- Xcurrent command is incomplete. In zsh, you can put the line
- Xon the buffer stack, using ESC-Q, and type some other com-
- Xmands. The next time a prompt is printed, the gcc line will
- Xbe popped off the stack and put in the editing buffer
- Xautomatically; you can then enter the proper library name
- Xand press return (or, ESC-Q again and look for some other
- Xlibraries whose names you forgot).
- X
- XA similar situation: what if you forget the option to gcc
- Xthat finds bugs using AI techniques? You could either use
- XESC-Q again, and type man gcc, or you could press ESC-H,
- Xwhich essentially does the same thing; it puts the current
- Xline on the buffer stack, and executes the command run-help
- Xgcc, where run-help is an alias for man.
- X
- XAnother interesting command is ESC-A. This executes the
- Xcurrent line, but retains it in the buffer, so that it
- Xappears again when the next prompt is printed. Also, the
- Xcursor stays in the same place. This is useful for execut-
- Xing a series of similar commands:
- X
- X% cc grok.c -g -lc -lgl -lsun -lmalloc -Bstatic -o b.out
- X% cc fubar.c -g -lc -lgl -lsun -lmalloc -Bstatic -o b.out
- X% cc fooble.c -g -lc -lgl -lsun -lmalloc -Bstatic -o b.out
- X
- X
- X
- XThe ESC-' command is useful for managing the shell's quoting
- Xconventions. Let's say you want to print this string:
- X
- Xdon't do that; type 'rm -rf \*', with a \ before the *.
- X
- X
- XAll that is necessary is to type it into the editing buffer:
- X
- X% don't do that; type 'rm -rf \*', with a \ before the *.
- X
- X
- Xpress ESC-' (escape-quote):
- X
- X
- X
- X
- X
- X
- X - 27 -
- X
- X% 'don'\''t do that; type '\''rm -rf \*'\'', with a \ before the *.'
- X
- X
- Xthen move to the beginning and add the echo command.
- X
- X% echo 'don'\''t do that; type '\''rm -rf \*'\'', with a \ before the *.'
- Xdon't do that; type 'rm -rf \*', with a \ before the *.
- X
- X
- XLet's say you want to create an alias to do this echo com-
- Xmand. This can be done by recalling the line with ^P and
- Xpressing ESC-' again:
- X
- X% 'echo '\''don'\''\'\'''\''t do that; type '\''\'\'''\''rm -rf
- X\*'\''\'\'''\'', with a \ before the *.'\'''
- X
- X
- Xand then move to the beginning and add the command to create
- Xan alias.
- X
- X% alias zoof='echo '\''don'\''\'\'''\''t do that; type '\''\'\'''\''rm
- X-rf \*'\''\'\'''\'', with a \ before the *.'\'''
- X% zoof
- Xdon't do that; type 'rm -rf \*', with a \ before the *.
- X
- X
- X
- XAnother interesting option is MENUCOMPLETE. This affects
- Xthe way TAB works. Let's look at the /vmunix example again:
- X
- X% setopt menucomplete
- X% ls /vmuTAB
- X% ls /vmunixTAB
- X% ls /vmunix.new.kernelmap.oldTAB
- X% ls /vmunix.old_
- X
- X
- XEach time you press TAB, it displays the next possible com-
- Xpletion. In this way, you can cycle through the possible
- Xcompletions until you find the one you want.
- X
- XThe AUTOMENU option makes a nice compromise between this
- Xmethod of completion and the regular method. If you set
- Xthis option, pressing the TAB key repeatedly after an ambi-
- Xguous completion will cycle through the possible comple-
- Xtions.
- X
- XBindings
- X
- XEach of the above editor commands was actually a function
- Xbound by default to a certain key. The real names of the
- Xcommands are:
- X
- Xexpand-or-complete TAB
- Xpush-line ESC-Q
- Xrun-help ESC-H
- Xaccept-and-hold ESC-A
- Xquote-line ESC-'
- X
- X
- X
- X
- X
- X
- X - 28 -
- XThese bindings are arbitrary; you could change them if you
- Xwant. For example, to bind accept-line to ^Z:
- X
- X% bindkey '^Z' accept-line
- X
- X
- XAnother idea would be to bind the delete key to delete-char;
- Xthis might be convenient if you use ^H for backspace.
- X
- X% bindkey '^?' delete-char
- X
- X
- XOr, you could bind ^X^H to run-help:
- X
- X% bindkey '^X^H' run-help
- X
- X
- XOther examples:
- X
- X% bindkey '^X^Z' universal-argument
- X% bindkey ' ' magic-space
- X% bindkey -s '^T' 'uptime
- X> '
- X
- X
- Xuniversal-argument multiplies the next command by 4. Thus
- X^X^Z^W might delete the last four words on the line. If you
- Xbind space to magic-space, then csh-style history expansion
- Xis done on the line whenever you press the space bar.
- X
- XThe -s flag to bindkey specifies that you are binding the
- Xkey to a string, not a command. Thus bindkey -s '^T'
- X'uptime\n' lets you VMS lovers get the load average whenever
- Xyou press ^T.
- X
- XIf you have a NeXT keyboard, the one with the | and \ keys
- Xvery inconveniently placed, the following bindings may come
- Xin handy:
- X
- X% bindkey -s '\e/' '\\'
- X% bindkey -s '\e=' '|'
- X
- X
- XNow you can type ALT-/ to get a backslash, and ALT-= to get
- Xa vertical bar. This only works inside zsh, of course;
- Xbindkey has no effect on the key mappings inside talk or
- Xmail, etc.
- X
- XAnother use of the editor is to edit the value of variables.
- XFor example, an easy way to change your path is to use the
- Xvared command:
- X
- X% vared PATH
- X> /u/pfalstad/scr:/u/pfalstad/bin/sun4:/u/maruchck/scr:/u/subbarao/bin:/u/maruc
- Xhck/bin:/u/subbarao/scripts:/usr/princeton/bin:/usr/ucb:/usr/bin:/bin:/usr/host
- Xs:/usr/princeton/bin/X11:/./usr/lang:/./usr/etc:/./etc
- X
- X
- XYou can now edit the path. When you press return, the con-
- Xtents of the edit buffer will be assigned to PATH.
- X
- X
- X
- X
- X
- X - 29 -
- XParameter Substitution
- X
- XIn zsh, parameters are set like this:
- X
- X% foo=bar
- X% echo $foo
- Xbar
- X
- X
- XSpaces before or after the = are frowned upon:
- X
- X% foo = bar
- Xzsh: command not found: foo
- X
- X
- XAlso, set doesn't work for setting parameters:
- X
- X% set foo=bar
- X% set foo = bar
- X% echo $foo
- X
- X%
- X
- X
- XNote that no error message was printed. This is because
- Xboth of these commands were perfectly valid; the set builtin
- Xassigns its arguments to the positional parameters ($1, $2,
- Xetc.).
- X
- X% set foo=bar
- X% echo $1
- Xfoo=bar
- X% set foo = bar
- X% echo $3 $2
- Xbar =
- X
- X
- XIf you're really intent on using the csh syntax, define a
- Xfunction like this:
- X
- X% set () {
- X> eval "$1$2$3"
- X> }
- X% set foo = bar
- X% set fuu=brrr
- X% echo $foo $fuu
- Xbar brrr
- X
- X
- XBut then, of course you can't use the form of set with
- Xoptions, like set -F (which turns off filename generation).
- XAlso, the set command by itself won't list all the parame-
- Xters like it should. To get around that you need a case
- Xstatement:
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X - 30 -
- X
- X% set () {
- X> case $1 in
- X> -*|+*|'') builtin set $* ;;
- X> *) eval "$1$2$3" ;;
- X> esac
- X> }
- X
- X
- XFor the most part, this should make csh users happy.
- X
- XThe following sh-style operators are supported in zsh:
- X
- X% unset null
- X% echo ${foo-xxx}
- Xbar
- X% echo ${null-xxx}
- Xxxx
- X% unset null
- X% echo ${null=xxx}
- Xxxx
- X% echo $null
- Xxxx
- X% echo ${foo=xxx}
- Xbar
- X% echo $foo
- Xbar
- X% unset null
- X% echo ${null+set}
- X
- X% echo ${foo+set}
- Xset
- X
- X
- XAlso, csh-style : modifiers may be appended to a parameter
- Xsubstitution.
- X
- X% echo $PWD
- X/home/learning/pf/zsh/zsh2.00/src
- X% echo $PWD:h
- X/home/learning/pf/zsh/zsh2.00
- X% echo $PWD:h:h
- X/home/learning/pf/zsh
- X% echo $PWD:t
- Xsrc
- X% name=foo.c
- X% echo $name
- Xfoo.c
- X% echo $name:r
- Xfoo
- X% echo $name:e
- Xc
- X
- X
- XThe equivalent constructs in ksh (which are also supported
- Xin zsh) are a bit more general and easier to remember. When
- Xthe shell expands ${foo#pat}, it checks to see if pat
- Xmatches a substring at the beginning of the value of foo.
- XIf so, it removes that portion of foo, using the shortest
- Xpossible match. With ${foo##pat}, the longest possible
- X
- X
- X
- X
- X
- X - 31 -
- Xmatch is removed. ${foo%pat} and ${foo%%pat} remove the
- Xmatch from the end. Here are the ksh equivalents of the :
- Xmodifiers:
- X
- X% echo ${PWD%/*}
- X/home/learning/pf/zsh/zsh2.00
- X% echo ${PWD%/*/*}
- X/home/learning/pf/zsh
- X% echo ${PWD##*/}
- Xsrc
- X% echo ${name%.*}
- Xfoo
- X% echo ${name#*.}
- Xc
- X
- X
- Xzsh also has upper/lowercase modifiers:
- X
- X% xx=Test
- X% echo $xx:u
- XTEST
- X% echo $xx:l
- Xtest
- X
- X
- Xand a substitution modifier:
- X
- X% echo $name:s/foo/bar/
- Xbar.c
- X% ls
- Xfoo.c foo.h foo.o foo.pro
- X% for i in foo.*; mv $i $i:s/foo/bar/
- X% ls
- Xbar.c bar.h bar.o bar.pro
- X
- X
- XOne possible source of confusion is the fact that in zsh,
- Xthe result of parameter substitution is not split into
- Xwords. Thus, this will not work:
- X
- X% srcs='glob.c exec.c init.c'
- X% ls $srcs
- Xglob.c exec.c init.c not found
- X
- X
- XThis is considered a feature, not a bug. If splitting were
- Xdone by default, as it is in most other shells, functions
- Xlike this would not work properly:
- X
- X$ ll () { ls -F $* }
- X$ ll 'fuu bar'
- Xfuu not found
- Xbar not found
- X
- X% ll 'fuu bar'
- Xfuu bar not found
- X
- X
- XOf course, a hackish workaround is available in sh (and
- Xzsh):
- X
- X
- X
- X
- X
- X - 32 -
- X
- X% setopt shwordsplit
- X% ll () { ls -F "$@" }
- X% ll 'fuu bar'
- Xfuu bar not found
- X
- X
- XIf you like the sh behaviour, zsh can accomodate you:
- X
- X% ls ${=srcs}
- Xexec.c glob.c init.c
- X% setopt shwordsplit
- X% ls $srcs
- Xexec.c glob.c init.c
- X
- X
- XAnother way to get the $srcs trick to work is to use an
- Xarray:
- X
- X% unset srcs
- X% srcs=( glob.c exec.c init.c )
- X% ls $srcs
- Xexec.c glob.c init.c
- X
- X
- Xor an alias:
- X
- X% alias -g SRCS='exec.c glob.c init.c'
- X% ls SRCS
- Xexec.c glob.c init.c
- X
- X
- XAnother option that modifies parameter expansion is RCEX-
- XPANDPARAM:
- X
- X% echo foo/$srcs
- Xfoo/glob.c exec.c init.c
- X% setopt rcexpandparam
- X% echo foo/$srcs
- Xfoo/glob.c foo/exec.c foo/init.c
- X% echo foo/${^srcs}
- Xfoo/glob.c foo/exec.c foo/init.c
- X% echo foo/$^srcs
- Xfoo/glob.c foo/exec.c foo/init.c
- X
- X
- X
- XShell Parameters
- X
- XThe shell has many predefined parameters that may be
- Xaccessed. Here are some examples:
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X - 33 -
- X
- X% sleep 10 &
- X[1] 3820
- X% echo $!
- X3820
- X% set a b c
- X% echo $#
- X3
- X% echo $ARGC
- X3
- X% ( exit 20 ) ; echo $?
- X20
- X% false; echo $status
- X1
- X
- X
- X($? and $status are equivalent.)
- X
- X% echo $HOST $HOSTTYPE
- Xdendrite sun4
- X% echo $UID $GID
- X701 60
- X% cd /tmp
- X% cd /home
- X% echo $PWD $OLDPWD
- X/home /tmp
- X% ls $OLDPWD/.getwd
- X/tmp/.getwd
- X
- X
- X~+ and ~- are short for $PWD and $OLDPWD, respectively.
- X
- X% ls ~-/.getwd
- X/tmp/.getwd
- X% ls -d ~+/learning
- X/home/learning
- X% echo $RANDOM
- X4880
- X% echo $RANDOM
- X11785
- X% echo $RANDOM
- X2062
- X% echo $TTY
- X/dev/ttyp4
- X% echo $VERSION
- Xzsh v2.00.03
- X% echo $USERNAME
- Xpf
- X
- X
- X
- XThe cdpath variable sets the search path for the cd command.
- XIf you do not specify . somewhere in the path, it is assumed
- Xto be the first component.
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X - 34 -
- X
- X% cdpath=( /usr ~ ~/zsh )
- X% ls /usr
- X5bin dict lang net sccs sys
- X5include etc lector nserve services tmp
- X5lib export lib oed share ucb
- Xadm games local old skel ucbinclude
- Xbin geac lost+found openwin spool ucblib
- Xboot hosts macsyma_417 pat src xpg2bin
- Xdemo include man princeton stand xpg2include
- Xdiag kvm mdec pub swap xpg2lib
- X% cd spool
- X/usr/spool
- X% cd bin
- X/usr/bin
- X% cd func
- X~/func
- X% cd
- X% cd pub
- X% pwd
- X/u/pfalstad/pub
- X% ls -d /usr/pub
- X/usr/pub
- X
- X
- XPATH and path both set the search path for commands. These
- Xtwo variables are equivalent, except that one is a string
- Xand one is an array. If the user modifies PATH, the shell
- Xchanges path as well, and vice versa.
- X
- X% PATH=/bin:/usr/bin:/tmp:.
- X% echo $path
- X/bin /usr/bin /tmp .
- X% path=( /usr/bin . /usr/local/bin /usr/ucb )
- X% echo $PATH
- X/usr/bin:.:/usr/local/bin:/usr/ucb
- X
- X
- XThe same is true of CDPATH and cdpath:
- X
- X% echo $CDPATH
- X/usr:/u/pfalstad:/u/pfalstad/zsh
- X% CDPATH=/u/subbarao:/usr/src:/tmp
- X% echo $cdpath
- X/u/subbarao /usr/src /tmp
- X
- X
- XIn general, parameters with names in all lowercase are
- Xarrays; assignments to them take the form:
- X
- Xname=( elem ... )
- X
- X
- XParameters with names in all uppercase are strings. If
- Xthere is both an array and a string version of the same
- Xparameter, the string version is a colon-separated list,
- Xlike PATH.
- X
- XHISTFILE is the name of the history file, where the history
- Xis saved when a shell exits.
- X
- X
- X
- X
- X
- X - 35 -
- X
- X% zsh
- Xphoenix% HISTFILE=/tmp/history
- Xphoenix% SAVEHIST=20
- Xphoenix% echo foo
- Xfoo
- Xphoenix% date
- XFri May 24 05:39:35 EDT 1991
- Xphoenix% uptime
- X 5:39am up 4 days, 20:02, 40 users, load average: 2.30, 2.20, 2.00
- Xphoenix% exit
- X% cat /tmp/history
- XHISTFILE=/tmp/history
- XSAVEHIST=20
- Xecho foo
- Xdate
- Xuptime
- Xexit
- X% HISTSIZE=3
- X% history
- X 28 rm /tmp/history
- X 29 HISTSIZE=3
- X 30 history
- X
- X
- X
- XIn zsh, if you say
- X
- X% >file
- X
- X
- Xthe command cat is normally assumed:
- X
- X% >file
- Xfoo!
- X^D
- X% cat file
- Xfoo!
- X
- X
- END_OF_FILE
- if test 49646 -ne `wc -c <'doc/intro.txt.01'`; then
- echo shar: \"'doc/intro.txt.01'\" unpacked with wrong size!
- fi
- # end of 'doc/intro.txt.01'
- fi
- if test -f 'help/autoload' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'help/autoload'\"
- else
- echo shar: Extracting \"'help/autoload'\" \(274 characters\)
- sed "s/^X//" >'help/autoload' <<'END_OF_FILE'
- X autoload [ name ... ]
- X For each of the names (which are names of functions),
- X create a function marked undefined. The fpath variable
- X will be searched to find the actual function definition
- X when the function is first referenced.
- END_OF_FILE
- if test 274 -ne `wc -c <'help/autoload'`; then
- echo shar: \"'help/autoload'\" unpacked with wrong size!
- fi
- # end of 'help/autoload'
- fi
- if test -f 'src/Makefile.sample' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'src/Makefile.sample'\"
- else
- echo shar: Extracting \"'src/Makefile.sample'\" \(1851 characters\)
- sed "s/^X//" >'src/Makefile.sample' <<'END_OF_FILE'
- X#! /bin/make -f
- X# Makefile for zsh
- X# generated by buildzsh
- X
- XAUX=buildzsh
- X
- XSRC=builtin.c cond.c exec.c glob.c hist.c init.c jobs.c lex.c loop.c \
- Xmath.c mem.c params.c parse.c subst.c table.c text.c utils.c watch.c \
- Xzle_bindings.c zle_hist.c zle_main.c zle_misc.c zle_move.c zle_refresh.c \
- Xzle_tricky.c zle_utils.c zle_vi.c zle_word.c
- X
- XHEADER=funcs.h zle.h zsh.h ztype.h
- X
- XPROTO=builtin.pro cond.pro exec.pro glob.pro hist.pro init.pro jobs.pro \
- Xlex.pro loop.pro math.pro mem.pro params.pro parse.pro subst.pro table.pro \
- Xtext.pro utils.pro watch.pro zle_bindings.pro zle_hist.pro zle_main.pro \
- Xzle_misc.pro zle_move.pro zle_refresh.pro zle_tricky.pro zle_utils.pro \
- Xzle_vi.pro zle_word.pro
- X
- XOBJS=builtin.o cond.o exec.o glob.o hist.o init.o jobs.o lex.o loop.o \
- Xmath.o mem.o params.o parse.o subst.o table.o text.o utils.o watch.o \
- Xzle_bindings.o zle_hist.o zle_main.o zle_misc.o zle_move.o zle_refresh.o \
- Xzle_tricky.o zle_utils.o zle_vi.o zle_word.o
- X
- XBINDIR=/usr/local/bin
- XMANDIR=/usr/local/man/man1
- X
- X# Debugging flags
- XDFLAGS = # -DQDEBUG
- X
- X# For gcc 2.3.3
- X# CC=gcc -fpcc-struct-return
- X# CFLAGS= -O2 -g -Wall -Wno-implicit -Wno-parentheses -Wno-comment $(DFLAGS)
- X
- XCC=cc
- XCFLAGS= -O
- XLIBS= -ltermcap
- X
- XZSHPATH=zsh
- X
- X.SUFFIXES: .c .o .pro
- X
- X.c.o:
- X $(CC) $(CFLAGS) $(DFLAGS) -c $<
- X
- X.c.pro:
- X sed -n '/\/\*\*\/$$/{N;s/^\([^(]*\).*\/\*\*\/.\(.*\)/\1 DCLPROTO((\2))/p;}' $< | sed -e 's/;/,/g' -e 's/,))$$/));/' -e 's/(({))$$/((void));/' >$@
- X
- Xall: $(PROTO) $(ZSHPATH)
- X
- X$(ZSHPATH): $(OBJS)
- X $(CC) -o $(ZSHPATH) $(OBJS) $(LIBS) $(LFLAGS)
- X
- Xtags: /tmp
- X ctags *.[cy]
- X
- X# I hate this next line
- X$(OBJS): config.h zsh.h zle.h signals.h ztype.h funcs.h
- X
- Xparams.o: version.h
- X
- Xclean:
- X rm -f *.o *.pro zsh core
- X
- Xcleanall:
- X rm -f *.o *.pro zsh core Makefile signals.h config.h
- X
- Xinstall: zsh
- X install -s -m 755 zsh $(BINDIR)
- X install -m 444 ../man/man1/zsh.1 $(MANDIR)
- END_OF_FILE
- if test 1851 -ne `wc -c <'src/Makefile.sample'`; then
- echo shar: \"'src/Makefile.sample'\" unpacked with wrong size!
- fi
- # end of 'src/Makefile.sample'
- fi
- echo shar: End of archive 3 \(of 22\).
- cp /dev/null ark3isdone
- MISSING=""
- for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 22 archives.
- rm -f ark[1-9]isdone ark[1-9][0-9]isdone
- else
- echo You still must unpack the following archives:
- echo " " ${MISSING}
- fi
- exit 0
-
- exit 0 # Just in case...
-