Switching from bash

The Linux Magazine ran a couple simple articles explaining how the Bash user can change to Zsh. Here is the link for the one about switching Making the Transition to zsh. Also the zsh distribution comes with a script bash2zshprompt that converts bash prompts to zsh. This script is not installed, it is only available in the zsh source distribution under Misc/ (also at: bash2zshprompt)

Bash completions

Zsh can handle bash completions functions. The latest development version of zsh has a function bashcompinit, that when run will allow zsh to read bash completion specifications and functions. This is documented in the zshcompsys man page. To use it all you need to do is run bashcompinit at any time after compinit. It will define complete and compgen functions corresponding to the bash builtins.

bash completions are typically stored in files which must be sourced (bash doesn't have autoloadable functions) I use the following function to source these files:

bash_source() {
  alias shopt=':'
  alias _expand=_bash_expand
  alias _complete=_bash_comp
  emulate -L sh
  setopt kshglob noshglob braceexpand

  source "$@"

This uses aliases to avoid the bash shopt builtin and to avoid problems with common bash functions that have the same name as zsh ones. It also sets zsh options to best emulate bash.

It is probably better to use function autoloading however.

The have() function commonly used with bash completions doesn't work in zsh 4.0. The following is a replacement which you can use instead.

have() {
  unset have
  (( ${+commands[$1]} )) && have=yes

Keep in mind that it is much better to rewrite completion functions for zsh than to spend much time getting a bash function to work with this.

Bash keybindings

Bash actually uses GNU Readline to manage keybingings while zsh handles them by itself.

One thing which often bites those with bash background is a gesture for the "get the Nth argument of the just executed command into the edit buffer" action. By default, it's done by the M-n, C-M-y Readline gesture, where "n" is the argument's position, which starts from 0 and counts from left to right (C-M-y by itself picks the first argument, i.e. the agrument number 1, or the second word in the line). For instance, if you have just executed

$ foo bar baz quux

you can start entering

$ frobnicate 

and then type M-2, C-M-y to get that baz inserted before the cursor position to get

$ frobnicate baz

zsh has its own approach to this which is implemented in a somewhat reversed way compared to Readline's: you can use M-. to get the last argument (works in Readline to) or M-n-. to get the Nth argument, counted from right to left, starting from 1.

You can also count from left to right, using 0 and negative counts: -1 picks the first argument from the left (the second word in the line), -2–the second argument and so on, while 0 picks the leftmost word, i.e. the command name itself, as in Readline. But note that while you can use the Esc key instead of Meta (which is usually Alt on PC keyboards) for both M-. and M-n-. gestures, it won't work for the case of negative arguments, so you have to press your Meta key, type the argument number followed by a dot, then release the Meta key.

So to get that second command line argument from our example using zsh, we would type either M-2-. or M–2-..

The handling of command arguments explained here is described in the zshzle manual page.


For cygwin users: Cygwin by default creates a shortcut to bash, you can create a shortcut for zsh by using the mkzsh command that comes with the cygwin version of zsh. Run "mkzsh -h" to get usage information.

convert/bash.txt · Last modified: 2015/12/05 07:47 by spamkiller