Using dash as /usr/bin/sh? - think twice

Tuesday, Jun 4, 2019
Linux shell

You will find some advices to use another shell than bash as /usr/bin/sh (or /bin/sh). One of the major reasons why this is proposes is speed. While bash is a comfortable shell it is rather big. So when using a smaller alternative to bash as sh scripts might be faster.

Arguably this makes sense if you script a lot. If not that argument is pretty useless. So unless you do shell scripts I would argue not to change the system default. And even if you do, you should think twice.

why to stick with bash

Even though dash is usually a goo replacement and with most scripts there is no problem there are differences that prevent scripts written with the bash features in mind will not be executable with dash.

Let’s take a deeper look into one script:

# /usr/bin/i3exit

# with openrc use loginctl
[[ $(cat /proc/1/comm) == "systemd" ]] && logind=systemctl || logind=loginctl

case "$1" in
        i3-msg exit
        dm-tool switch-to-greeter
        blurlock && $logind suspend
        blurlock && $logind hibernate
        $logind reboot
        $logind poweroff
        echo "== ! i3exit: missing or invalid argument ! =="
        echo "Try again with: lock | logout | switch_user | suspend | hibernate | reboot | shutdown"
        exit 2

exit 0

When executed with dash linked as sh you will notice an error if you call it from your favorite terminal:

/usr/bin/i3exit: 5: /usr/bin/i3exit: [[: not found

Uh, what is this? The syntax in use by this i3 script (on Manjaro) is not compatible with dash. Unfortunately, the command must be successfully if you want to use any command that controls the login state such as shutdown or reboot.

This just happened to me as I could not shutdown my computer with the commands of my i3 config. So before exchanging the sh link you should think twice. And consider that your distribution’s developers probably decided for some reason why sh links to the specific shell.