32

I thought /bin/sh was a symlink to my shell of choice. I've always used bash, so I assumed that /bin/sh would point to /bin/bash. It turns out, though, that it points to /bin/dash.

It gets funnier. I start dash and do echo $SHELL and it prints /bin/bash (so they're basically the same?). However, the man page of dash is completely different from the man page of bash (so they're not the same?).

Dennis Williamson
  • 62,149
  • 16
  • 116
  • 151
aioobe
  • 371
  • 1
  • 4
  • 16
  • 1
    @wzzrd, Is this question linux-specific? – aioobe Oct 21 '10 at 07:54
  • 1
    sigh, I can't upvote all of these nice answers, since I need 15 rep. I feel handicapped as I have 18k on stackoverflow :-/ – aioobe Oct 21 '10 at 08:03
  • 4
    mmm dash.. what about /bin/crash (for gdb fans), /bin/slash (an austerity program), /bin/mash (hard times in Korea), /bin/sash (for cheerleaders), /bin/thrash (hard on your HDD), /bin/flash (but only if you encrypt your data), /bin/stash (good luck finding it later), /bin/cash (you're always in-the-money), /bin/pash (romancing the PC), /bin/gash (aaargggh!). – PP. Oct 21 '10 at 08:11
  • @PP Dash is short for Debian Almquist Shell. And your forgetting /bin/clash (for all your dependency problems). @aioobe, as far as I know, Dash is only used in Linux, but there is nothing stopping you from building it on some *BSD. But I can remove the 'linux' tag again. No problem. – wzzrd Oct 21 '10 at 09:00
  • 2
    @PP - I'd read /bin/thrash for Metal music fans, and /bin/slash for fans of 80's rock band lead guitarists... :-P – gWaldo Oct 21 '10 at 12:12
  • 1
    The reason `echo $SHELL` prints `/bin/bash` is because that variable is set for the default shell that starts when you login rather than the current shell you're running. Start ksh or zsh from a Bash prompt and `echo $SHELL` will still say `/bin/bash`. Use `ps` to see what's currently running. – Dennis Williamson Oct 21 '10 at 15:38
  • @Dennis Williamson: Nice, I didn't know that. I had assumed it was a flaw in / feature missing from dash. – wzzrd Oct 22 '10 at 07:16
  • Your shell of choice is stored in the account database (`/etc/passwd`). `/bin/sh` always points to Bourne Shell (or compatible). – user1686 Oct 22 '10 at 20:23
  • Wait, what? To find your currently executing shell you should not need to use ps, I use do `echo $0` – J. M. Becker Mar 17 '15 at 18:29

4 Answers4

49

Debian and Ubuntu switched to dash (iirc) because of a couple of things. First of all, Bash has become big over the years. In fact, the /bin/bash binary on my Ubuntu 8.04 system is almost ten times (!) as big as /bin/dash. Now, that does not matter much for day to day shell use, but it does matter in the following situations:

  • Dash is much smaller and thus loads faster, which is a boon for init-scripts. If you have to start a lot of them, loading Dash instead of Bash each time, speeds things up considerably.
  • Because of the smaller size of Dash, Debian and Ubuntu are able to shave off a pretty big chunk of the size of their initrd, leaving more room for other stuff (and again, speeding things up).

The downside of using Dash instead of Bash for scripting, is that a lot of people use syntactical niceties only Bash has, the so-called Bashisms. Examples of Bashisms are substrings, like this:

echo $SHELL
/bin/bash
a=1234567890
echo ${a}
1234567890
echo ${a:3}
4567890
echo ${a:3:1}
4

And this:

echo ${a#123}
4567890

Dash, on the other hand mainly aims to be POSIX compliant (and no more than that), will give you a Bad substition error if you try this:

echo $SHELL
/bin/dash 
# actually, it will read /bin/bash above, because if you just run dash
# it will not set the $SHELL variable :)
a=1234567890
echo ${a}
1234567890
echo ${a:3}
dash: Bad substitution

This will matter if you use /bin/sh (and therefore dash) as the interpreter for your shellscripts and use Bashisms in them. Debian and Ubuntu have nice wiki pages about Bashisms and why they are bad in shellscripts in general and init-scripts in particular. Therefore, you should consciously choose whether you need /bin/sh or /bin/bash as the interpreter for your script.

Dash is not supposed to be used as the default shell on your systems. Just use Bash for that. For portability of your scripts, you can use Dash as the interpreter to increase the odds the scripts will run on other Linux flavors and Unixes.

wzzrd
  • 10,409
  • 2
  • 35
  • 47
  • 1
    If you write scripts with Bashisms, please specify `/bin/bash`; many non-Linux systems have actual `sh` shells which aren't even close to compatible with `bash`. – Chris S Oct 21 '10 at 15:49
  • `echo ${a#123}` is not a bashism, it's part of the POSIX Parameter expansion spec. http://pubs.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html You just don't get the more advanced sed style Bash ones, The posix ones are substring style + simple expansion characters. Meaning, POSIX also allows `echo ${a#*6}` – J. M. Becker Mar 17 '15 at 18:33
4

Take a look here: https://wiki.ubuntu.com/DashAsBinSh maybe It will help.

microspino
  • 434
  • 1
  • 4
  • 11
1

dash is a lightweight bash replacement, im assuming you use ubuntu which changed to it a few years ago.

Its not overly good though, imho. http://forums.debian.net/viewtopic.php?f=20&t=45116

Sirex
  • 5,499
  • 2
  • 33
  • 54
0

Since not all shells set $SHELL when run, you find out your current shell with:

echo $0

If it gives an error, it's csh, otherwise it's the argv[0] you were invoked with, which is typically the shell, perhaps with a leading - hyphen, to indicate that it's a login shell.

This isn't guaranteed, since argv[0] is under the control of the invoking process, but it is in practice the most reliable approach.

Phil P
  • 3,080
  • 1
  • 16
  • 19