Book HomeBook TitleSearch this book

A.8. zsh

zsh is a powerful interactive shell and scripting language with many features found in ksh, bash, and tcsh, as well as several unique features. zsh has most of the features of ksh88 but few of ksh93. It is freely available and should compile and run on just about any modern version of Unix. Ports for other operating systems are also available. The zsh home page is http://www.zsh.org. The current version is 4.0.2.

In this section we cover:

A.8.1. Extended Globbing

A very useful feature is the recursive glob[152] operator, **. For example, a recursive grep is simple to construct:

[152] Globbing is technical slang for wildcard expansion.

grep foo **/*.c

Or to recursively find all files or directories named core, try:

print **/core

Another useful feature is glob qualifiers. There are many of these, for example, to print out only regular files in the current directory:

print *(.)

or just the directories:

print *(/)

Combining these with the recursive glob operator can be handy. We can improve the above example of finding core files by limiting the search to regular files only:

print **/core(.)

Another qualifier is U for file system objects you own. The following prints all files you own in /tmp and below:

print /tmp/**/*(U)

The glob qualifiers can also be combined. For example, using the socket file keyword = in combination with U, it's easy to find socket files in /tmp and below that you own:

print /tmp/**/*(U=)

File size qualifiers are also available. For example, to find all files in your home directory that are greater than 10 megabytes in size:

print ~/**/*(Lm+10)

And file permission qualifiers are also available. For example, the W qualifier selects world-writable file system objects. You can use it to find all directories in your home directory and below that are owned by you and that are world-writeable:

print ~/**/*(UW/)

See zshexpn(1) for more information.

A.8.2. Completion

The zsh completion system is extremely sophisticated. The main idea is that any time you are about to type something on the command line, if you hit TAB, zsh will try to complete it. zsh comes with many defaults for completion and is also fully customizable.

To get a full set of default completion features, run the following commands (normally in your ~/.zshrc startup file):

autoload -U compinit
compinit

Now let's look at some examples. We represent the TAB key in examples as [TAB].

First, zsh is smart about doing completions. For example, cd[TAB] only expands directories, thus eliminating completion noise.

Have you ever been frustrated because you can't think of exactly the name of the command you want to find more information on, and man -k[153] hasn't been configured on your system? Well, zsh will complete available man pages for you:

[153] This does a keyword search of an online database extracted from the man pages.

g@sifl:pts/7% man zsh[TAB]
zsh           zshcompctl    zshcontrib    zshmodules    zshzftpsys  
zshall        zshcompsys    zshexpn       zshoptions    zshzle      
zshbuiltins   zshcompwid    zshmisc       zshparam

Or maybe you want to find out a process name or PID you want to kill:

g@sifl:pts/2% kill [TAB]
 9652 pts/2    00:00:00 zsh                                                    
 9653 pts/2    00:00:00 ps                                                     

For finger, it expands users:

g@sifl:pts/7% finger o[TAB]
odin	omg	oof        operator	orb

and hosts:

g@sifl:pts/7% finger oof@[TAB]
brak	localhost 	sifl 	zorak

Using the distributed compdef function, you can define your own completions, using either your own custom functions or the completion functions that come with zsh. For example, the distribution defines the kill command to use the _pids distribution function to provide process identifiers. You can also use it to define completion for other commands, such as the Solaris pstack command:

compdef _pids pstack

Once this is done, you can apply completion to the pstack command like so:

g@sifl:pts/7% pstack [TAB]
13606 pts/7    00:00:00 zsh                                                    
13607 pts/7    00:00:00 ps

Another very useful distribution completion function is _gnu_generic. This can be applied to any command that uses the GNU --long-option command-line option conventions. The zsh distribution specifies many GNU commands to complete with this function (such as tar):

g@sifl:pts/7% tar --v[TAB]
--verbose      --verify       --version      --volno-file 

And this is just the tip of the proverbial iceberg. There is much more to the zsh completion system; see zshcompsys(1) for the (gory) details.

A.8.3. Command-Line Editor

The zsh command-line editor is extremely powerful. It has several unique features, including multiline editing and an input buffer stack. The multiline command editor makes composing small scripts on the command line much easier then just having one line to edit with.

The input buffer stack comes in very handy. While you are typing a command, you can type ESC q, and the current line is pushed onto the buffer stack. The input line is then cleared, and you can type another command. When that has been executed, the previous line is popped off the stack and you can continue with that command. See zshzle(1) for more details.

A.8.4. Prompts and Prompt Themes

While most modern shells have customizable prompts, zsh raises it to an art form. One of the unique features is a right side prompt, RPROMPT, which is very useful for holding the current directory. This in turn removes clutter from the left hand prompt:

g@sifl:pts/2% RPROMPT='%~'
g@sifl:pts/2%                                    ~/src/xemacs-21.1.14

Also, you can define colors and bold fonts, and the prompt can be more than one line.

And as the notion of themes[154] has become popular in GUIs such as GNOME, zsh prompt themes can be defined; the distribution ships with several to choose from. To enable prompt themes, add these lines to your ~/.zshrc:

[154] Some popular GUIs, such as GNOME, support themes. Rather than having one immutable look and feel, they can be changed to different styles, or themes. The distributions of these GUIs often contain several to choose from. Some of these tend to emulate other GUI's, while others are new and are mostly fun window dressing.

autoload -U promptinit
promptinit

To see what themes are available, run:

g@sifl:pts/2% prompt -l                                             ~
Currently available prompt themes:
adam1 adam2 bart bigfade clint elite2 elite fade fire off oliver
redhat suse zefram

To enable a theme, use the -s option. For example:

g@sifl:pts/7% prompt -s bart                                        ~
sifl [prompt -s bart] ~                              01-10-04 11:58PM
g@sifl:pts/7%                                                       ~

You can see that bart is a two-line prompt with several components such as the host name, the previous command, the current directory, and the date and time. See zshcontrib(1) for more details on prompt themes.

A.8.5. Differences Between zsh and ksh

This section is derived from information in the zsh FAQ.

Most features of ksh88 (and hence also of the Bourne shell, sh) are implemented in zsh; problems can arise because the implementation is slightly different. Note also that not all ksh's are the same either. This is based on the 11/16/88f version of ksh; differences from ksh93 are more substantial.

As a summary of the status:

  1. Because of all the options, it is not safe to assume a general zsh run by a user will behave as if sh or ksh compatible.

  2. Invoking zsh as sh or ksh (or if either is a symbolic link to zsh) sets appropriate options and improves compatibility (from within zsh itself, calling ARGV0=sh zsh will also work).

  3. From Version 3.0 onward, the degree of compatibility with sh under these circumstances is very high: zsh can now be used with GNU configure or perl's Configure, for example.

  4. The degree of compatibility with ksh is also high, but a few things are missing: for example, the more sophisticated pattern-matching expressions are different for versions before 3.1.3 -- see the detailed list below.

  5. Also from 3.0, the command emulate is available: emulate ksh and emulate sh set various options as well as changing the effect of single-letter option flags, as if the shell had been invoked with the appropriate name. Including the command emulate sh; setopt localoptions in a shell function turns on sh emulation for that function only. In 4.0 (and in 3.0.6 through 8), this can be abbreviated as emulate -L sh.

The classic difference is word splitting: zsh keeps the result of plain $variable as one word, even if the variable contains white space. This trips up many beginning zsh users. The answer is to set SH_WORD_SPLIT for backward compatibility. The next most classic difference is that unmatched glob patterns cause the command to abort; set NO_NOMATCH for those.

zsh has a large set of options which increase ksh compatibility, though maybe decreasing zsh's abilities: see the manual entries for the details. If invoked as ksh, the shell sets suitable options.

Here are some differences from ksh which might prove significant for ksh programmers, some of which may be interpreted as bugs. Note that this list is deliberately rather full and that most of the items are fairly minor. Those marked with Figure perform in a ksh-like manner if the shell is invoked with the name ksh or if emulate ksh is in effect. Capitalized words with underscores in their names refer to shell options.

Syntax
Command-line substitutions, globbing, etc.

Table A-1. ksh/zsh pattern equivalents

ksh zsh Meaning
!(foo) ^foo

Anything but foo.

  foo1~foo2

Anything matching foo1 but not foo2.[156]

@(foo1|foo2|...) (foo1|foo2|...)

One of foo1 or foo2 or ...

?(foo) (foo|)

Zero or one occurrences of foo.

*(foo) (foo)#

Zero or more occurrences of foo.

+(foo) (foo)##

One or more occurrences of foo.

[156] Note that ~ is the only globbing operator to have a lower precedence than /. For example, **/foo~*bar* matches any file in a subdirectory called foo, except where bar occurred somewhere in the path (e.g. users/barstaff/foo will be excluded by the ~ operator). As the ** operator cannot be grouped (inside parentheses it is treated as *), this is the way to exclude some subdirectories from matching a **.

Command execution
  • Figure There is no ENV variable (use /etc/zshrc, ~/.zshrc; note also $ZDOTDIR).

  • $PATH is not searched for commands specified at invocation without -c.

Aliases and functions
  • The order in which aliases and functions are defined is significant: function definitions with () expand aliases.

  • Aliases and functions cannot be exported.

  • There are no tracked aliases: command hashing replaces these.

  • The use of aliases for key bindings is replaced by bindkey.

  • Figure Options are not local to functions (use LOCAL_OPTIONS; note this may always be unset locally to propagate options settings from a function to the calling level).

  • Functions defined with function funcname { body ;} behave the same way as those defined with funcname () { body ;}. In ksh93, only the former behave as true functions, and the latter behave as if the body were read from a file with the dot command.

Traps and signals
  • Figure Traps are not local to functions. The option LOCAL_TRAPS is available from 3.1.6.

  • TRAPERR has become TRAPZERR (this was forced by UNICOS which has SIGERR).

Editing
  • The options emacs, gmacs, and viraw are not supported. Use bindkey to change the editing behavior: set -o emacs becomes bindkey -e and set -o vi becomes bindkey -v; for gmacs, go to emacs-mode and use bindkey \^t gosmacs-transpose-characters.

  • The keyword option does not exist and set -k is instead interactivecomments.

  • Figure Management of histories in multiple shells is different: the history list is not saved and restored after each command. The option SHARE_HISTORY appeared in 3.1.6 and is set in ksh compatibility mode to remedy this.

  • \ does not escape editing chars (use CTRL-V).

  • Not all ksh bindings are set (e.g. ESC #; try ESC q).

  • Figure # in an interactive shell is not treated as a comment by default.

Built-in commands
  • Some built-ins (r, autoload, history, integer, ...) are aliases in ksh.

  • There is no built-in command newgrp: use alias newgrp="exec newgrp".

  • jobs has no -n flag.

  • read has no -s flag.

Other idiosyncrasies
  • select always redisplays the list of selections on each loop.



Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.