Boston Linux & Unix (BLU) Home | Calendar | Mail Lists | List Archives | Desktop SIG | Hardware Hacking SIG
Wiki | Flickr | PicasaWeb | Video | Maps & Directions | Installfests | Keysignings
Linux Cafe | Meeting Notes | Blog | Linux Links | Bling | About BLU

BLU Discuss list archive


[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

bash scripting across linux and solaris



Matt wrote, about using #!/bin/sh:
> Strictly speaking, 'bash' is a superset of 'sh'.  Some linux systems make
> 'sh' a symlink to 'bash', but not all (ubuntu IIRC is one that doesn't), and
> solaris certainly doesn't.
>
> This matters since a linux distro like fedora that just uses bash for sh
> will not enforce 'sh-only' syntax, whereas ubuntu and solaris, which use
> actual 'sh' binaries, will.

I've long thought that bash takes note of how it's invoked and, if you
invoke it as sh, it limits its behavior to the sh subset. Well, this
wouldn't be the first time something I've long thought turns out to be
wrong.

I note that in Debian, sh is a symlink to bash but under Ubuntu it's a
symlink to dash, so it is a separate binary but still not sh itself,
although the manpage for dash appears to be the plain manpage for BSD
sh, with no mention of dash.

>From reading the bash manpage (for the version supplied with Debian
and Ubuntu), I note that bash cares whether it's invoked as bash or sh
and behaves differently. In particular, calling it sh enforces
POSIX-compliance. Alas, I can't tell whether posixly-correct behavior
is the same as the sh subset.

An experiment is in order. Array support is a feature of bash not
included in sh, so let's try that.

On Ubuntu:

$ bash
$ A[2]=foo
$ echo ${A[2]}
foo
$ exit

$ sh
$ A[2]=foo
sh: A[2]=foo: not found
$ echo ${A[2]}
sh: Bad substitution
$ exit

Ok, this is what I (and Matt) would expect, since Ubuntu has a
separate binary for sh. Since Ubuntu is a Debian derivative, it hardly
seems necessary ;-), but let's try Debian anyway:

$ bash
$ A[2]=foo
$ echo ${A[2]}
foo
$ exit

$ sh
$ A[2]=foo
$ echo ${A[2]}
foo
$ exit

Yikes! sh is bash! And I use Debian for servers, where it really matters!

This is certainly valuable to know; thanks, Matt!

> >From the school of hard knocks: unless you're an expert 'sh' programmer,
> don't develop scripts that start with #!/bin/sh on fedora and the like,
> since you can't be sure they'll work on systems that actually use the shell
> you're telling it to use.

Hmm...My view has been that system (or critical application) shell
scripts should always be written in sh because we can't guarantee that
bash or csh or ksh or zsh, etc, will be on any particular platform.
This may seem overly-conservative since one can always install the
shell in question, but you can't always install a maintainer who knows
it. Sadly, as Matt's reference to "an expert 'sh' programmer" reminds
us, neither can we assume sh expertise in a maintainer. On the other
hand, we can assume that someone entrusted with such a job will have
at least a basic knowledge of sh and will tread carefully when making
changes.

All well and good, but Matt is absolutely correct in saying that this
is dangerous if you can't guarantee your sh script actually works
under sh. Fortunately, I do most of my development under Ubuntu (and
my testing under Debian, before releasing new production code to
Debian) so it looks like I lucked out. I'll need to warn all the
colleagues that I misinformed, who are now maintaining my stuff!

Thanks again, Matt!

Ted

ps. Seems dash isn't exactly sh, but much closer than bash:
http://en.wikipedia.org/wiki/Debian_Almquist_shell

tbr






BLU is a member of BostonUserGroups
BLU is a member of BostonUserGroups
We also thank MIT for the use of their facilities.

Valid HTML 4.01! Valid CSS!



Boston Linux & Unix / webmaster@blu.org