zsh: a REALLY nice alternative for bash
June 18th, 2008 edited by TinchoArticle submitted by Danilo Martins. Guess what? We still need you to submit good articles about software you like!
After years using ZSH instead of BASH, I still don’t understand why isn’t everybody using it. ZSH is a complete shell that will certainly make your life easier. Give it a try.
First of all, you need it installed (duh). APT and its super cow powers will do this for you. You can simply use:
$ sudo apt-get install zsh
and you should be all set. Alternatively, you can install the package “zsh-beta”, but it tends to crash once in a while… ZSH is available on any repository of Debian and Ubuntu.
To try it out, you can simply type zsh, but you wouldn’t be very happy with the result. Let’s personalize it first. First of all, create a file named .zshrc
on your home directory. Inside, you should put the text listed here (note: see the commented lines —be sure to try each of them out sometime)
Editor’s note: I’ve moved the sample script to a separate link, to ease cut&paste. Also, note that if you run zsh from Debian testing/unstable for the first time without a .zshrc
file, it will greet you with an initial configuration dialog.
Now do run zsh. If you see a different prompt (specially if you did not comment the prompt lines on the .zshrc
example above), it’s working. Now, it’s time you see what you can do with this.
First example. Lets suppose you’re doing a long command (cat /etc/mailcap | grep "^audio" | sed s/mplayer/gmplayer) and forget the command syntax for the sed
program. You simply move your cursor to the command “sed” and press ALT-H. This should open the man page for sed
. After you close the man page, you will automatically be returned with the command you were typing.
Second example. You’re connecting to a remote host using SSH. You remember that you want to use the X11 forwarding, but you don’t remember how to do this. Then, you type “ssh -” and press TAB. Yes, ZSH auto-completes not only files, but also command parameters. Be sure to try it out with whatever command you want to use.
Third example. You have a SSH key to a remote host, and you wish to copy a file from there using SCP. But you do not remember exactly where the file is. You simply type “scp user@remotehost:/home/myuser/myf”, press TAB and watch ZSH doing its amazing trick. Not only ZSH auto-completes files and parameters, but also remote files (remember that for this to work you need to have the RSA/DSA key on the remote host).
Fourth example. You want to install a Debian package (I love this one), but you don’t remember (or are too lazy to) type the whole name of the package. Instead, you simply type “apt-get install mysql-client” and press TAB, and watch ZSH magically auto-completing the package name. If you have more than one, it will list all available below, and if you keep pressing TAB it will complete through each one of them, one at a time. And yes, not only ZSH auto-completes files, parameters and remote files, but it also auto-completes package names. Well, I think we had enough of the “auto-complete” examples, didn’t we?
Fifth example. Yesterday you used a loooooong command and you are too lazy to type it all again. You also do not want to press UP until it appears. Instead of it, you simply type the beginning of the command and try the ALT-P combination. ZSH will auto-complete your command from the history. You can keep using ALT-P and swapping to the previous entries. If you missed it, ALT-N gets you to the next.
Last example. You typed apt-gey install foo bar foo2 bar2 foo3 bar3 foo4 bar4 ... foo239 bar239 and pressed ENTER. Oh, shit, apt-gey does not exist. Instead of pressing UP, HOME, going to “gey” and changing it to “get”, you can simply use ^gey^get. This is a shortcut to “repeat the last command, but all occurrences of “gey” are now “get”.
If you liked the way ZSH works and want to use it as your default shell, you can always use the chsh
command, and put /usr/bin/zsh
there. It’s now your default shell.
Enjoy!
June 18th, 2008 at 3:18 pm
The ^ substitution command in the last example is present in bash… and I’m not sure how zsh’s ALT-P is significantly better than bash’s CTRL-R/CTRL-S, at least in this example…
June 18th, 2008 at 3:33 pm
The third and fourth example are both present in Bash :)
(For the fourth you have to copy the completion code from /etc/bash.bashrc).
Nice article nevertheless.
June 18th, 2008 at 7:31 pm
What is line echo “\e[1;9]\e[8]” supposed to do?
I see \e[1;9]\e[8] in my prompt.
And I got this error:
.zshrc:unalias:109: no such hash table element: run-help
June 18th, 2008 at 7:48 pm
I’ve been using zsh for some time, and the best feature over bash for me is the way the completion menu is displayed and hidden, without moving up all the previous lines.
June 18th, 2008 at 8:09 pm
Yes, yes, yes, yes !!
I’ve been using zsh for a year and now I can’t stand bash :) zsh is amazingly powerfull, and quickly becomes essential. Clever command completion in apt-get, svn and so on are really time-saving
June 18th, 2008 at 8:52 pm
I’ve seen zsh proponents praising their shell loudly, and always wanted to know if switching to it would be worth my time. Therefore I’m very happy to see a post like this.
Unfortunately, bash already does everything described in these particular examples, except for looking up the man page with alt-h. Surely there must be more?
June 18th, 2008 at 9:27 pm
The reason I will never use zsh is because it has insane defaults. Just look at that config-file you present to newbies.
bash isn’t that good in that sense either. My hope is for fish… once it supports vi-mode. Until then bash works ok.
June 18th, 2008 at 9:47 pm
Nice, although most of the completion bits can be achieved in bash by calling “source /etc/bash_completion”
Also I have a problem with the smart completion:
/home/omry/.zshrc:115: unmatched ‘
June 18th, 2008 at 10:23 pm
For the “.zshrc … unmatched ‘” entries, there is a typo on line 9:
RPS1=’‘
should be
RPS1=”
there was a back-tic in there instead of a single quote.
So I’m not sure what happened with the formatting on the page but mine came across a little jacked-up so here is the reformatted one, although I don’t know how well it will display in this posting:
### Uncomment the following line if you want to use the “command not found” Ubuntu command
#. /etc/zsh_command_not_found
### These are a really nice view of the command line. If you do not like it, comment all lines.
PS1=’33[30;47m\u:\w>33[0m '
prompt='%U%n%u:%B%~%b# '
PROMPT2='%_> '
#echo '\e[1;9]\e[8]‘
RPS1=”
### General config sets
LS_COLORS=’no=00:fi=00:di=01;34:ln=01;36:pi=40;33:so=01;35:bd=40;33;01:cd=40;33;01:ex=01;32:mi=5;31;46:or=5;31;46:*.cmd=01;32:*.exe=01;32:*.com=01;32:*.btm=01;32:*.bat=01;32:*.deb=01;31:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.gz=01;31:*.jpg=01;35:*.gif=01;35:*.bmp=01;35:*.xbm=01;35:*.xpm=01;35:*.png=01;35:*.ppm=01;35:’
LS_OPTIONS=’-F -B –color=auto’
### Default definitions
## I use MOST as my default pager. You should too, but it’s up to you
#PAGER=/usr/bin/most
command_oriented_history=1
HISTCONTROL=ignoreboth
ulimit -c unlimited
umask 022
mesg y
### LS and V aliases
alias ls=”ls $LS_OPTIONS” #–format=vertical
alias v=”ls $LS_OPTIONS –format=long”
alias l=”v”
### Export everything so far
export PS1 NLSPATH PAGER MAIL LS_COLORS LS_OPTIONS LIBRARY_PATH C_INCLUDE_PATH CPLUS_INCLUDE_PATH EDITOR TERM XFILESEARCHPATH
### History configuration
export HISTFILE=$HOME/.zsh_history
export HISTSIZE=8192
export SAVEHIST=8192
### CD shortcuts
export CDPATH=.:~
### List of file extensions you wish to ignore on a ls
export FIGNORE=”~:.o”
### These are very interesting. I will explain some of them at the end
setopt share_history
setopt appendhistory
setopt autocd
setopt automenu
setopt autopushd
setopt autoresume
setopt complete_in_word
setopt extended_glob
setopt hist_ignoredups
setopt hist_ignorespace
setopt list_types
setopt mailwarning
setopt no_flowcontrol
setopt no_hup
setopt no_notify
setopt printexitvalue
setopt pushd_ignoredups
setopt pushd_silent
### Making sure your keyboard will work on any terminal
bindkey “^[[1~” beginning-of-line
bindkey “^[[4~” end-of-line
bindkey “^[[2~” overwrite-mode
bindkey “^[[3~” delete-char
bindkey “^[[6~” end-of-history
bindkey “^[[5~” beginning-of-history
bindkey “^[^I” reverse-menu-complete
bindkey “^[OA” up-line-or-history
bindkey “^[[A” up-line-or-history
bindkey “^[[B” down-line-or-history
bindkey “^[OB” down-line-or-history
bindkey “^[OD” backward-char
bindkey “^[OC” forward-char
bindkey “^P” history-beginning-search-backward
bindkey “^N” history-beginning-search-forward
bindkey “^[[[A” run-help
bindkey “^[[[B” which-command
bindkey “^[[[C” where-is
bindkey “^D” list-choices
### See for yourself, at the end
alias -g …=’../..’
alias -g ….=’../../..’
alias -g …..=’../../../..’
### Push History from previous sessions
fc -R $HISTFILE
### Forcing the rehash
_force_rehash() {
(( CURRENT == 1 )) && rehash
return 1
}
### Loading the completion style
zstyle ‘:completion:*’ completer
_oldlist _expand _force_rehash _complete
### Aliasing “run-help”
#unalias run-help
autoload run-help
### Loading the compinit
autoload -U compinit
compinit
June 18th, 2008 at 10:27 pm
WOW…it totally jacked-up the formatting again. If I copy/paste from vi to here, the page is making single-quotes in to back-ticks and so-forth. The author might just want to publish a text file that can preserve the proper formatting.
Other than that, good article and thank you for the information.
June 18th, 2008 at 10:37 pm
Sorry folks, Wordpress is being craptastic again. I’ve tried to fix the quotes issue with no luck, WP still tries to be more clever…
June 19th, 2008 at 12:38 am
>The author might just want to publish a >text file that can preserve the proper >formatting.
Please do this!
All those different “‘` make me dizzy…
June 19th, 2008 at 12:41 am
###
# Here is my debugged version of the config
### Uncomment the following line if you want to use the “command not found” Ubuntu command
#. /etc/zsh_command_not_found
### These are a really nice view of the command line. If you do not like it, comment all lines.
PS1=’33[30;47m\u:\w>33[0m ‘
prompt=’%U%n@%m%u:%B%~%b%# ‘
PROMPT2=’%_> ‘
### General config sets
LS_COLORS=’no=00:fi=00:di=01;34:ln=01;36:pi=40;33:so=01;35:bd=40;33;01:cd=40;33;01:ex=01;32:mi=5;31;46:or=5;31;46:*.cmd=01;32:*.exe=01;32:*.com=01;32:*.btm=01;32:*.bat=01;32:*.deb=01;31:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.gz=01;31:*.jpg=01;35:*.gif=01;35:*.bmp=01;35:*.xbm=01;35:*.xpm=01;35:*.png=01;35:*.ppm=01;35:’
LS_OPTIONS=”-F -B –color=auto”
### Default definitions
## I use MOST as my default pager. You should too, but it’s up to you
#PAGER=/usr/bin/most
command_oriented_history=1
HISTCONTROL=ignoreboth
ulimit -c unlimited
umask 022
mesg y
### LS and V aliases
alias ls=”ls $LS_OPTIONS –format=vertical”
alias v=”ls $LS_OPTIONS –format=long”
alias l=”v”
### Export everything so far
export PS1 NLSPATH PAGER MAIL LS_COLORS LS_OPTIONS LIBRARY_PATH C_INCLUDE_PATH CPLUS_INCLUDE_PATH EDITOR TERM XFILESEARCHPATH
### History configuration
export HISTFILE=$HOME/.zsh_history
export HISTSIZE=8192
export SAVEHIST=8192
### CD shortcuts
export CDPATH=.:~
### List of file extensions you wish to ignore on a ls
export FIGNORE=”~:.o”
### These are very interesting. I will explain some of them at the end
setopt share_history
setopt appendhistory
setopt autocd
setopt automenu
setopt autopushd
setopt autoresume
setopt complete_in_word
setopt extended_glob
setopt hist_ignoredups
setopt hist_ignorespace
setopt list_types
setopt mailwarning
setopt no_flowcontrol
setopt no_hup
setopt no_notify
setopt printexitvalue
setopt pushd_ignoredups
setopt pushd_silent
### Making sure your keyboard will work on any terminal
bindkey ‘^[[1~’ beginning-of-line
bindkey ‘^[[4~’ end-of-line
bindkey ‘^[[2~’ overwrite-mode
bindkey ‘^[[3~’ delete-char
bindkey ‘^[[6~’ end-of-history
bindkey ‘^[[5~’ beginning-of-history
bindkey ‘^[^I’ reverse-menu-complete
bindkey ‘^[OA’ up-line-or-history
bindkey ‘^[[A’ up-line-or-history
bindkey ‘^[[B’ down-line-or-history
bindkey ‘^[OB’ down-line-or-history
bindkey ‘^[OD’ backward-char
bindkey ‘^[OC’ forward-char
bindkey ‘^P’ history-beginning-search-backward
bindkey ‘^N’ history-beginning-search-forward
bindkey ‘^[[[A’ run-help
bindkey ‘^[[[B’ which-command
bindkey ‘^[[[C’ where-is
bindkey ‘^D’ list-choices
### See for yourself, at the end
alias -g …=’../..’
alias -g ….=’../../..’
alias -g …..=’../../../..’
### Push History from previous sessions
fc -R $HISTFILE
### Forcing the rehash
_force_rehash() {
(( CURRENT == 1 )) && rehash
return 1
}
### Loading the completion style
zstyle ‘:completion:*’ completer _oldlist _expand _force_rehash _complete
### Aliasing “run-help”
### unalias run-help
autoload run-help
### Loading the compinit
autoload -U compinit
compinit
June 19th, 2008 at 1:37 am
I seem to be plain stupid:
test@treehouse:~$ zsh
/home/test/.zshrc:10: bad pattern: 33[0m
/home/test/.zshrc:11: command not found: ‘
/home/test/.zshrc:15: command not found: 34:ln=01
/home/test/.zshrc:15: command not found: 36:pi=40
/home/test/.zshrc:15: command not found: 33:so=01
/home/test/.zshrc:15: command not found: 35:bd=40
/home/test/.zshrc:15: command not found: 33
/home/test/.zshrc:15: command not found: 01:cd=
/home/test/.zshrc:16: command not found: 40
/home/test/.zshrc:16: command not found: 33
/home/test/.zshrc:16: command not found: 01:ex=01
/home/test/.zshrc:16: command not found: 32:mi=5
/home/test/.zshrc:16: command not found: 31
/home/test/.zshrc:16: command not found: 46:or=5
/home/test/.zshrc:16: command not found: 31
/home/test/.zshrc:16: no matches found: 46:*.cmd=01
’33[30
June 19th, 2008 at 1:45 am
There. Sorry for all the confusion, now you can just wget or copy&paste the link to get the correct sample .zshrc file.
June 19th, 2008 at 12:11 pm
Thanks alot!
Great article ;)
June 19th, 2008 at 1:05 pm
Thanks for the article, but most of the examples you have given are available in Bash as well (at least >= 3.2.25).
Except from the hover -> Ctrl-H for man page trick, which personally I think would be much slower than just typing “man !!”.
I believe Bash relies on readline for auto-completion of switches etc, which needs to be configured for each program. If Zsh is more clever in how it auto-completes, I might be sold over.
June 19th, 2008 at 3:39 pm
For the record, ^ is originally a csh-ism.
I can’t live without zsh: it’s one of the first few things I install on a new machine along with sudo and openssh-server. I recommend spending a long time with a copy of man zshall(1), deciding what options you want to setopt, amongst other things.
I’m sure at least one of either debian and/or ubuntu has completions for apt-get inst[TAB] etc.
If anyone’s really interested I have a skeleton of my .zshrc here: http://spodzone.org.uk/packages/zshrc.txt.
June 19th, 2008 at 9:57 pm
Funny, the people that defend bash over zsh usually have not used both. I have, and let me say this: zsh is vastly superior. It is equal to bash, only better. For instance, bash would screw up the command line for me when it was too big and too close to the end of the window, while zsh would always do the proper thing.
Meanwhile, menu-completion, when properly configured, makes it even a descent replacement for midnight commander, walking the filesystem and selecting multiple files. There should be an example with this…
June 20th, 2008 at 6:03 am
cool! but i’m use yakuake (based on konsole), very suitable tool!
June 21st, 2008 at 10:25 am
The reason I’m not using zsh is because it doesn’t support UTF-8. A deal-breaker for me.
June 21st, 2008 at 10:43 am
to aoeu,
Actually it supports utf-8, but there are still a few zle issues. It really started to work in release 4.3.4.
June 21st, 2008 at 12:24 pm
> For instance, bash would screw > up the command line for me when > it was too big and too close to > the end of the window, while zsh would always do the proper thing.
Just because you mis-configured $PS1 doesn’t mean its bash’s fault.
June 21st, 2008 at 2:27 pm
Like others already stated, trick 3 and 4 can be achieved trough bash-completion.
Even the 2nd trick (remote file completion) works on bash with bash-completion. Several distro’s (including Ubuntu) even use bash-completion by default so all of this works out of the box.
The first trick is nice though - but not enough to switch - but for the 5th trick bash also has several shortcuts (!, !!, ^r etc). I think there was something similar in bash for the last trick but I’m not sure.
PS: aoeu, dvorak rocks ;-)
June 21st, 2008 at 3:55 pm
echo {1..9} works in zsh like in bash, but echo {a..z} doesnt work in zsh, which is usable in mirroring some pr0n sites ;)
June 21st, 2008 at 7:25 pm
If it is for your prOn…
[ag][414](~)setopt braceccl
[ag][415](~)echo {a-z}
a b c d e f g h i j k l m n o p q r s t u v w x y z
June 21st, 2008 at 9:08 pm
I’ve been using zsh for a month or so and I like it, but here are a few of my concerns:
Here’s part of output from a ps. The first column is the virtual memory space, the second is real memory usage:
VSS RSS COMMAND
5160 3568 /usr/local/bin/zsh
4424 2004 /usr/local/bin/bash
There are some quirky things to get used to such as:
zsh 4.3.6 (i386-portbld-freebsd7.0)% for ((x=0; x
June 21st, 2008 at 9:08 pm
zsh 4.3.6 (i386-portbld-freebsd7.0)% for ((x=0; x
June 21st, 2008 at 9:08 pm
bah… code is getting cut off
June 24th, 2008 at 5:43 pm
I switched back to bash from zsh long ago because 1) many systems I logged into did not have zsh and 2) bash now has all the interactive features that zsh had that I cared about, so I don’t know if this is available in zsh, but…
Shell conventions such as ^ and ! should be banned; they can be replaced by safer and more powerful: CTRL-r (reverse-search-history). So, instead of typing:
^ey^et
you could type:
C-r ey M-d et
(the spaces are there for clarity, but you shouldn’t type them). Why is this better?
* It is the same number of keystrokes (including modifier keys), but is more flexible because…
* If you wanted to actually edit a similar line further back in the history you can just type something like:
C-r ey C-r C-r M-d et
which would get you the third instance back of ey in the history.
* It is safer because you can SEE what you’re editing before executing it. For example if you were doing something like: ‘apt-cache pkgnames key | xargs apt-gey install’
If you did ^ey^et in that case it would change ‘key’ to ‘ket’ and leave ‘apt-gey’ unchanged. The C-r method is safer and faster in this case.
I still haven’t found any compelling reasons to switch back to zsh. What does zsh have on the interactive side that bash doesn’t that would make it compelling (rather than just adding those couple of features to bash?)?
June 26th, 2008 at 7:00 pm
Nice article.
I will stay with bash; as many comments have pointed out, bash seems to have these features (except for the alt-h one), so the article should have made that clear. The tone of the article misleads you into thinking bash doesn’t have these features.
For me, it is a matter of license. I prefer GPL, and thus bash. ^_^
- deego.
July 15th, 2008 at 3:45 pm
these are just shitty tips, no wonder why bash users don’t even want to try zsh. Zsh truly has exclusively nice features :
- glob qualifiers :
want to use only dirs in globbing ? “ls -d *(/)”
- many “do what i mean” (avoiding gotchas) like “.*” not matching “.” and “..” specifically (who would even want to match them ?)
- nice and useful packaged tools, such as “zmv” (”zmv ‘(*)’ ‘$1.ext’ “), or scripting tools (zparseopts, a getopt done right)
- some “menu” completion, allowing you to navigate faster than pressing “tab” a hundred times.
- and many more ! I greatly advise you to give a look at http://www.grml.org/zsh/zsh-lovers.html which contains valuable tips, not like this article, where the author hasn’t even verified what he wrote.
sad i’m posting a bit late…
November 20th, 2008 at 10:31 pm
Excellent job.
http://ubuntuforums.org/showthread.php?t=532957
this has some nice .zshrc scripts.
March 31st, 2009 at 4:12 am
This is a pretty terrible article; it doesn’t hit on any of the major features that zsh has over other shells.
EvilDead: The hidden tab completion is indeed excellent. It’s the main reason that I keep using zsh.