From Difference between bash and sh:

ABck to the question: If you have /bin/sh as a link to bash, then bash will not behave the same when called as /bin/sh as it does when called as /bin/bash. When called as sh, it will limit itself to mostly POSIX-compliance plus a limited set of extensions.

Does it mean that whenever I come across a shell script in Linux with a shebang to sh: #!/bin/sh, even if on that distro, bin/sh is a symlink to another shell, like dash or bash, it should be 100% compatible with the bourne shell, since it limit itself to a limited set of extension? So I could execute them in FreeBSD? Is there are exception to that? Or I should be safe to assume that it will work?

So if on a distro, bin/sh is a symlink to bin/bash, and a script use #!/bin/sh and the script contain bashism, it will not run, since bash will like be in sh mode?


No, if /bin/sh is a symlink to bash bash enters just posix mode - from man bash:

When invoked as sh, bash enters posix mode after the startup files are read.

If you now search for posix mode at the bash manpage you'll see that some shell builtins like time or source behave differently. That is all. bashishms like writing function before declaring a function or using source instead of . still will work but the commands may behave differently.

So if /bin/sh is a symlink to /bin/bash all typical bashishms still work.

For a pretty extensive list of differences in the Posix mode have a look at the bash reference manual.

  • So I guess the best thing to do is to test all script in the checkbashism tool. I heard that some distro, like Debian and Ubuntu (need confirmation for this one) had their bin/sh now symlink to dash. Does dash is compatible with the bourn shell? If yes, then at least all Debian and Ubuntu shell script should be fine under FreeBSD. – user1115057 Aug 6 '12 at 2:39
  • @user1115057 only shell scripts with /bin/sh as shebang. A shell script still can explicitly use /bin/bash. Anyway most shell scripts probably will run fine under /bin/sh but the problem will be the user tools, e.g. most shell script expect GNU userland which will probably be more of a problem than just some syntax error. I also added a link to the bash reference which lists the different behavior in posix mode – Ulrich Dangel Aug 6 '12 at 2:43
  • Ok from what I read, BSD use ash as their bin/sh, while Debian & Ubuntu use dash. If those shell are compatible, it mean I wont have anymore issue with shebang #!/bin/sh. But as you said, there will be other issue related to the userland... – user1115057 Aug 6 '12 at 3:33
  • @user1115057 dash is also not perfect, e.g wiki.ubuntu.com/DashAsBinSh/#echo anyway most shell scripts are rather simple and can be ported quite easily…good luck – Ulrich Dangel Aug 6 '12 at 3:45
  • But dash and ash are compatible right? – user1115057 Aug 6 '12 at 3:54

There seems to be some confusion around the Bourne shell. The Bourne shell was Unix shell decades ago, in the pre-POSIX days. Nowadays "sh" is an implementation or another of a shell that implements the POSIX specification, among which we have bash, pdksh, AT&T ksh, newer Almquist shells and their derivatives that have been made POSIX compliant (including the "sh" of some BSDs, other BSDs sh being based on pdksh and Debian ash (dash)). Even zsh has a mode in which it is mostly POSIX conformant.

The Bourne shell is not POSIX compliant, and can't be found on many system nowadays. Where the Bourne shell is found or where it's not, there will always be a "sh" that is POSIX compliant (and will not be the Bourne shell), generally in /bin while a notable (annoying) exception is Solaris.

Note that before the Bourne shell, and we're talking over 30 years ago, "sh" was the Thompson shell. We're not writing scripts compatible with the Thompson shell anymore. Similarly, we should stop thinking of "sh" as the Bourne shell.

Now "sh" is a specification, not many sometime incompatible variants of an implementation. That makes it a lot easier to write portable scripts. Just follow the specification.

That goes for "sh" and all the standard utilities (sed, cut, tr...)

  • +1 for "write to the specification." But sadly that's often not enough for portability. For example, what if one wants to use egrep-style patterns in sed? The specification doesn't provide for this. On systems with Gnu-based utilities (or BusyBox), you use sed -r. On systems with BSD-based utilities, you use sed -E. FreeBSD's sed accepts both, but Mac OS X's only accepts -E. And so on and so on. – dubiousjim Sep 23 '12 at 20:08
  • That's beside the point. The specification doesn't provide it, so you can't use it portably/POSIXly. If you use BREs, that will work on all POSIX conformant systems, that's a guarantee given by POSIX, that's why it's useful. Outside of POSIX as you say, there's no hope as seds either don't support ERE or support it with a different option or different ERE syntax. Note that EREs are less capable than BREs (only the syntax is extended in EREs to save you some typing. EREs can be translated to BREs, the contrary is not true (BRE's \(...\)\1 has no translation in standard EREs). – Stéphane Chazelas Sep 24 '12 at 6:12
  • 1
    I realize that (POSIX) EREs lack backreferences; in fact I've participated in editing that part of the standard. It's not correct that POSIX EREs are strictly less capable than BREs, since the in the current standard, alternation is not defined for BREs. However, I'm not aware of any regex engine which doesn't honor \| for BREs. I'm all for writing as portably as possible. I was only making the (I thought widely appreciated) observation that this can be painful, and sometimes writing to POSIX is simply not possible. Somewhere have links that exhibit many such perversions; will look for them. – dubiousjim Sep 24 '12 at 6:50
  • good point about alternation, I forgot about that and stand corrected. With sed, it's unlikely to be blocking though as you can use several expressions to match the alternate regexps. There's awk in the standard toolchest that can be used if EREs are needed. I very rarely find myself by the standard toolchest, and when I do, it's generally cases where another language like perl is more appropriate, but I do see your point (though I still think it's beside the point in this thread about writing portable scripts) – Stéphane Chazelas Sep 24 '12 at 7:18
  • An example I thought of offhand: shebang lines (at the top of every shell script) aren't specified in POSIX. Also, I'm not sure I've ever used a system that was 100% POSIX compliant. For example, POSIX says you can include newlines inside ${VAR:=stuff...here} but many shells don't let you, you have to put quotes around stuff...here. – dubiousjim Sep 24 '12 at 7:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.