Search

zsh: a REALLY nice alternative for bash

June 18th, 2008 edited by Tincho

Article 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!

Posted in Debian, Ubuntu |

34 Responses

  1. Tim G Says:

    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…

  2. N. Nobelis Says:

    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.

  3. davide Says:

    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

  4. EvilDead Says:

    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.

  5. Gliss Says:

    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

  6. Marius Gedminas Says:

    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?

  7. bluebirch Says:

    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.

  8. Omry Says:

    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 ‘

  9. spo0ner Says:

    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

  10. spo0ner Says:

    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.

  11. Tincho Says:

    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…

  12. memnon anon Says:

    >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…

  13. Scott Smith Says:

    ###
    # 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

  14. memnon anon Says:

    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

  15. Tincho Says:

    There. Sorry for all the confusion, now you can just wget or copy&paste the link to get the correct sample .zshrc file.

  16. memnon anon Says:

    Thanks alot!
    Great article ;)

  17. Sean Says:

    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.

  18. Tim Says:

    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.

  19. Leandro Penz Says:

    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…

  20. valfrom Says:

    cool! but i’m use yakuake (based on konsole), very suitable tool!

  21. aoeu Says:

    The reason I’m not using zsh is because it doesn’t support UTF-8. A deal-breaker for me.

  22. masterzen Says:

    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.

  23. Jeremy Says:

    > 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.

  24. Dieter_be Says:

    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 ;-)

  25. evil_core Says:

    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 ;)

  26. Ag Says:

    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

  27. Joey Says:

    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

  28. Joey Says:

    zsh 4.3.6 (i386-portbld-freebsd7.0)% for ((x=0; x

  29. Joey Says:

    bah… code is getting cut off

  30. Aaron Says:

    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?)?

  31. GPL Says:

    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.

  32. anon Says:

    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…

  33. cbsketchpad Says:

    Excellent job.

    http://ubuntuforums.org/showthread.php?t=532957

    this has some nice .zshrc scripts.

  34. RTS Says:

    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.