zsh

Main differences from bash

Pipes and subshells

In bash, every command in a pipeline is executed in a subshell. In zsh, the last command in a pipeline is executed in current shell. For example, the following code

var="before"
echo "after" | read var
echo $var

will print before in bash, but after in zsh.

Differences in quoting

In bash, you have to quote arguments in order to preserve white space:

# bash

function print_first_argument {
    echo "$1"
}

argument="has white space"
print_first_argument "$argument"

In Zsh, you don’t need the quotes, because of different evaluation order:

# zsh

function print_first_argument {
    echo $1
}

argument="has white space"
print_first_argument $argument

Wildcard Handling

When nothing matches a wildcard such as * in bash, it gets passed on as a literal * to the command, as if you had typed \*. However, zsh throws an error.

Bash:

duncan@K7DXS-Laptop-Arch:~/test$ echo *.txt
*.txt
duncan@K7DXS-Laptop-Arch:~/test$ touch abc.txt
duncan@K7DXS-Laptop-Arch:~/test$ echo *.txt
abc.txt
duncan@K7DXS-Laptop-Arch:~/test$ 

Zsh:

K7DXS-Laptop-Arch% echo *.txt   
abc.txt
K7DXS-Laptop-Arch% rm abc.txt 
K7DXS-Laptop-Arch% echo *.txt
zsh: no matches found: *.txt
K7DXS-Laptop-Arch% 

This is most noticeable in programs that use a literal *, such as find:

duncan@K7DXS-Laptop-Arch:~/test$ ls -R
.:
abc

./abc:
123.txt

Bash:

duncan@K7DXS-Laptop-Arch:~/test$ find -name *.txt
./abc/123.txt
duncan@K7DXS-Laptop-Arch:~/test$ 

Zsh:

K7DXS-Laptop-Arch% find -name *.txt
zsh: no matches found: *.txt
K7DXS-Laptop-Arch% find -name \*.txt
./abc/123.txt
K7DXS-Laptop-Arch% find -name '*.txt' # Notice single rather than double quotes
./abc/123.txt
K7DXS-Laptop-Arch% 

Aliases

Global aliases

In bash, aliases can only be placed at the beginning of of a command, but zsh supports aliases anywhere. If you place the following line in your $ZDOTDIR/.zshrc

alias -g G=' | grep -i'

You can then run

cat haystack.txt G "needle"

Suffix aliases (Added in zsh 4.2.x)

Suffix aliases allow you to tell zsh to open files with specify a program to open files with certain extensions. Examples:

alias -s c="emacs"
alias -s php="vim"
alias -s java="$EDITOR"

Now in your shell, if you have a php file, file.php, and you run the command

file.php

It will automatically open file.php in vim.


This modified text is an extract of the original Stack Overflow Documentation created by the contributors and released under CC BY-SA 3.0 This website is not affiliated with Stack Overflow