What is the difference between bash and sh?

27

4

I see two types of code being used:

#!/usr/bin/sh

and:

#!/user/bin/bash

I searched for this online and opinions vary a lot. The explanations I saw on most websites say that sh is older than bash, and that there is no real difference.

Does someone know the difference between these? Can you give me a practical example when to use one over the other?

Saif Bechan

Posted 2010-03-30T15:54:03.530

Reputation: 2 835

for a general overview over the different shells (not just sh and bash): http://en.wikipedia.org/wiki/Comparison_of_command_shells

– akira – 2010-03-30T16:13:21.620

1

Another great history here: http://www.faqs.org/faqs/unix-faq/shell/shell-differences/

– John Wright – 2010-03-31T21:58:07.590

Answers

33

bash is a superset of sh ie. everything you can do in sh you can do in bash.

Bash has more features (branching, builtins, arrays) making script easier to write. Some later *nix'es have /bin/sh as a link to /bin/bash

For a full explanation of what here's a tutorial

Nifle

Posted 2010-03-30T15:54:03.530

Reputation: 31 337

1Why don't they than just remove the sh. Or even better, why did they make a new thing called bash that has the same functions and more. They could have just added the functionalities to the sh command. Linux is always so confusing for noobs like me. – Saif Bechan – 2010-03-30T16:22:31.037

@Saif Bechan: I think it only seems confusing because you actually have a choice in software and I do not only mean which FTP client or whatever to use but also which application to use on a system level (like e.g. which shell you want to use). There is never the one and only right application. Applications evolve, requirements are changing, technology is evolving... – Felix – 2010-03-30T16:26:39.013

5

@Saif Bechan: One reason that the Bourne shell (sh) was not just extended is that Bash` was written by someone else. Also I bet there were license issues. Read the article about the Bourne Shell http://en.wikipedia.org/wiki/Bourne_shell

– Felix – 2010-03-30T16:32:52.040

@Saif : sh is part of the UNIX definition, and the posix standard. Many UNIX versions are not open source, and posix is not likely to make a particular GPL program part of the standard. So the difference is between people writing things for UNIX portability, and people writing specifically and only for Linux systems (where you can take bash's availability for granted) – Justin Smith – 2010-03-30T16:38:14.930

@felix: Yes I can see that ones you know all the little things the amount of flexibility it offers is huge. When developing things on unix I just need to take a little more time to figure out which version works best for me, and what the difference exactly is between everything. – Saif Bechan – 2010-03-30T16:39:07.237

7Removing sh would break a lot of scripts which expect it to be there and rely on the way it parses things. Linux users might not care, but people spending $$thousands on Solaris, AIX or HP-UX might be very annoyed. – njd – 2010-03-30T16:45:31.183

Yes I can understand the difference now in some detail. Thank you guys – Saif Bechan – 2010-03-30T16:56:23.573

3...and for even more fun, Ubuntu symlinks /bin/sh to dash. Dash isn't completely sh or bash compliant, but is supposed to start up faster. When the system is booting, all the init.d scripts run and I guess the time saved overall is worth it. – kbyrd – 2010-03-30T17:13:00.180

8I'm pretty sure Dash is completely sh compliant. The problem is that some people write scripts that say /bin/sh, but the script itself requires /bin/bash to work. Nobody notices a problem, because most of the time, /bin/sh simply points at /bin/bash. – davr – 2010-03-31T22:53:23.433

1@njd: wait, you're saying that bash isn't fully backwards-compatible with sh? Is there code which works on sh and doesn't work with bash? I was under the impression that the only advantage to using sh, and the raison d'être for dash, was that bash is necessarily bigger and slower (as mentioned in the BUGS section of its manpage) due to its expanded feature set. – intuited – 2010-06-29T02:03:38.097

@intuited: From the man-page "There are some subtle differences between bash and traditional versions of sh, mostly because of the POSIX specification.". Consider unintended shell expansions like "$(lotsa_dough)", which /bin/sh would parse literally, but bash would treat as a command substitution. – njd – 2010-06-30T09:59:08.393

@njd: $() has been supported since long ago by Almquist and Bourne shells.

– user1686 – 2011-03-21T09:18:50.007

8

@Saif: There is another reason why sh was not simply extended: Its source code is pure hell. Take a look. It's supposed to be C...

– user1686 – 2011-03-21T09:20:52.487

2

@grawity The other man page is also for ash, but it was called sh in 4.4BSD Lite2. The original Bourne shells don't support $().

– Lri – 2012-09-28T17:13:38.587

6

Traditionally, /bin/sh would have been the original Bourne shell, which has no history or command-line editing, and no job control.

For about the last 15 years or so, most Unixes have had the POSIX shell installed, or at least ksh or bash (which are very nearly POSIX-like), but still have the more limited shell in /bin/sh

The reason for that is so that older shell scripts which expect the older sh command will still work.
Since characters like {, } and ! have special meaning to bash, it's possible that an older shell script using those characters (without escaping them) could fail.
(The Bourne shell would take !!{1,2} literally, whereas bash would interpret that as a repeat of the previous command (!!) followed by a brace-expansion).

On Linux though, the sh command is almost always just a link to bash, with all the same features.

njd

Posted 2010-03-30T15:54:03.530

Reputation: 9 743

2Bash is supposed to (but doesn't always) behave in sh-compatibility mode if invoked as /bin/sh.

A lot of stuff broke when Ubuntu switched /bin/sh from linking to /bin/bash to linking to /bin/dash. The stuff that broke assumed bashisms when they should have been using standard sh. – Broam – 2010-03-31T22:07:43.137

4

sh can either mean Bourne shell or /bin/sh, which is some other (POSIX-conformant) shell on most modern platforms. "The POSIX shell" is the abstract shell defined by POSIX, which is implemented by bash in POSIX mode, or ksh or dash by default. /bin/sh is sometimes also called the POSIX shell, because it's a shell that conforms to POSIX on most platforms. The original Bourne shells aren't POSIX shells.

bashref has a list of differences between bash and Bourne shells. man bash has a list of changes when bash is invoked in POSIX mode.

/bin/sh is not a symlink or hard link on OS X, but it's almost the same size as /bin/bash:

$ ls -li /bin/{ba,}sh
29631757 -r-xr-xr-x  1 root  wheel  1333920 Jul 26 01:52 /bin/bash
29631758 -r-xr-xr-x  1 root  wheel  1334000 Jul 26 01:52 /bin/sh

man bash:

If bash is invoked with the name sh, it tries to mimic the startup behavior of historical versions of sh as closely as possible, while conforming to the POSIX standard as well.

The mimicking of Bourne shells is otherwise pretty limited. bash +B (Bourne) would actually disable features like brace expansion.

$ sh
$ echo {a,b}
a b
$ echo $BASH_VERSION
3.2.48(1)-release
$ bash +B
$ echo {a,b}
{a,b}

But even if you disable POSIX mode, echo behaves like echo -e by default:

$ sh
$ shopt -uo posix
$ echo '1\b2'
2

/bin/sh is dash on Ubuntu, so some bashisms work with /bin/sh on OS X but not Ubuntu.

If you actually want to write scripts for (something like) the original Bourne shells, you could use #!/usr/bin/env bash +B instead.

I think it's easier to write scripts for bash than to avoid features that aren't part of the POSIX specifications or Bourne shells or test everything with other shells.

Lri

Posted 2010-03-30T15:54:03.530

Reputation: 34 501

2

Actually, even though /bin/sh may be a link to /bin/bash, if started up as sh it behaves differently. From the bash manpage:

If bash is invoked with the name sh, it tries to mimic the startup behavior of historical versions of sh as closely as possible, while conforming to the POSIX standard as well.

So as sh, it tries to emulate historical sh behavior. As bash, it tries to be as useful as possible as an interactive login shell.

KeithB

Posted 2010-03-30T15:54:03.530

Reputation: 8 506

2

On many systems and on Solaris in particular, bash is dynamically linked while sh is statically linked. This may pose a security threat, for this reason root user should only use /bin/sh as shell (if you ever need to log as root).

Alessandro Vozza

Posted 2010-03-30T15:54:03.530

Reputation: 246

2Also may be useful in an emergency if you did something bad with ldconfig or your /lib directory is wiped out for some reason. – LawrenceC – 2012-03-06T17:56:45.850