|
|
Subscribe / Log in / New account

A tale of two shells: bash or dash

By Rebecca Sobol
July 29, 2009

A reoccurring topic on Debian lists is the use of dash (Debian Almquist Shell) as opposed to bash (GNU Bourne-Again Shell). Currently /bin/sh defaults to bash on a Debian system, but some would like the default to be dash.

Ubuntu made this switch three years ago, with the release of Ubuntu 6.10. Note that the default login shell remains bash, only the default /bin/sh used in shell scripts has been changed. Why did Ubuntu make this change?

The major reason to switch the default shell was efficiency. bash is an excellent full-featured shell appropriate for interactive use; indeed, it is still the default login shell. However, it is rather large and slow to start up and operate by comparison with dash. A large number of shell instances are started as part of the Ubuntu boot process. Rather than change each of them individually to run explicitly under /bin/dash, a change which would require significant ongoing maintenance and which would be liable to regress if not paid close attention, the Ubuntu core development team felt that it was best simply to change the default shell. The boot speed improvements in Ubuntu 6.10 were often incorrectly attributed to Upstart, which is a fine platform for future development of the init system but in Ubuntu 6.10 was primarily running in System V compatibility mode with only small behavioural changes. These improvements were in fact largely due to the changed /bin/sh.

The Debian EeePC project also notes that dash provides faster boot times. So why hasn't Debian already made this switch? In fact this was a release goal for Lenny.

Part of the problem is "bashisms" - use of non-standard bash features - in shell scripts. There is a lengthy list of bugs tagged with goal-dash that contain bashisms. These are being worked on, package by package. While some users report that they have already made the switch without problems, others will find many of their user scripts will have bashisms.

One can use checkbashisms (man page) to look for bashisms, but for users with lots of scripts using /bin/sh this could be a long and painful process.

Here's a sample of checkbashisms output for the package apertium:
checkbashisms' output:
> possible bashism in ./usr/bin/apertium-preprocess-corpus-lextor line 47
> ('((' should be '$(('): if ((length(w)>0) && (index(w,"^")>0)) {
> possible bashism in ./usr/bin/apertium line 9 ('function' is useless):
> function message

Examples of bashisms include use of $RANDOM, the select, let, and source keywords, shell arithmetic, the -e option to echo, and many other things.

Debian policy looks at SUSv3 Shell Command Language and states:

If a shell script requires non-SUSv3 features from the shell interpreter other than those listed above, the appropriate shell must be specified in the first line of the script (e.g., #!/bin/bash) and the package must depend on the package providing the shell (unless the shell package is marked "Essential" [policy 3.6], as in the case of bash).

You may wish to restrict your script to SUSv3 features plus the above set when possible so that it may use /bin/sh as its interpreter. If your script works with dash (originally called ash), it probably complies with the above requirements, but if you are in doubt, use /bin/bash.

This raises the issue of whether dash should be "essential" [see Debian policy section 3.8]. bash is "essential" meaning that it must be installed on every Debian system. If dash does not become "essential" then every script with /bin/sh as its interpreter must depend on dash to insure that it is installed and usable by /bin/sh (once the change is made).

That this change will be made is mostly not under debate, it is more a matter of when it will be fully implemented. Those that oppose the move simply want a choice, which exists using dpkg-reconfigure dash. Meanwhile users should be looking at their own scripts to see if they will break once /bin/sh defaults to dash.


to post comments

Has anyone considered extending dash?

Posted Aug 6, 2009 2:39 UTC (Thu) by dwheeler (guest, #1216) [Link] (9 responses)

If dash implements the Single Unix Spec, then it does not HAVE to do more to meet that formal spec. But some of the "bashisms" are convenient, would add little to the size of dash, and would make it FAR easier to use dash as an alternative. Is anyone looking into what bashisms are "most popular" yet small, and perhaps should be implemented in dash as well? And, if they should, perhaps modifying the Single Unix Spec so that it includes those, too?

I don't think that dash should add everything that bash already does; we already have bash. But it might be easier to use dash as /bin/sh if dash added a few of bash's conveniences.

Has anyone considered extending dash?

Posted Aug 6, 2009 14:07 UTC (Thu) by fbriere (guest, #4961) [Link] (8 responses)

Is anyone looking into what bashisms are "most popular" yet small, and perhaps should be implemented in dash as well?

Section 10.4 of Policy lists three such exceptions (namely, "echo -n", "test -a/-o" and "local"). They are not in the standard, but are deemed useful enough to be required of any shell claiming /bin/sh.

And, if they should, perhaps modifying the Single Unix Spec so that it includes those, too?

I wouldn't hold my breath on that one. :)

But it might be easier to use dash as /bin/sh if dash added a few of bash's conveniences.

Any script requiring bash features can always specify #!/bin/bash on its first line.

The issue with bashisms is not about people needing specific bash features, but about people not knowing that they are bash-specific. The bash(1) manpage doesn't state which features are standard and which are not, and the standard itself is not always easy to find (or read, for that matter). The dash(1) manpage can serve as a gentler approach, but even dash doesn't strive for strict standards complicance.

As a result, most script maintainers are blisfully ignorant of what the standard requires. (I myself strive to adhere to the standard, yet I didn't know until recently that "." searching the current directory is a bashism.)

So, unless dash implements all of bash (which would rather defeat the point), any transition is bound to hit a few bumps on that road.

Has anyone considered extending dash?

Posted Aug 7, 2009 18:43 UTC (Fri) by giraffedata (guest, #1954) [Link] (1 responses)

Any script requiring bash features can always specify #!/bin/bash on its first line.

And pay the price of Bash. The point is that it would be great if we could get the cheapness of Dash from many programs that were written for Bash.

The issue with bashisms is not about people needing specific bash features, but about people not knowing that they are bash-specific.
That's an important issue, but not the one that is the subject of this article. The instant issue with bashisms is that they exist today in scripts that specify #!/bin/sh, and that complicates making /bin/sh = Dash. Making Dash understand some bashisms can't completely solve the problem, but it could ameliorate it considerably.

The bash(1) manpage doesn't state which features are standard and which are not,

It also doesn't state which features are available in which versions of Bash, which makes it hard to write a #!/bin/bash program that works everywhere. And Perl and myriad programming libraries have the same issue. I'm expanding on this point to encourage people who write manuals for such things to consider including that information.

Has anyone considered extending dash?

Posted Aug 9, 2009 6:18 UTC (Sun) by jlokier (guest, #52227) [Link]

Not only that, but occasionally a new version of Bash will deliberately break something which worked in an older version of Bash. Just like Perl, really, but without the helpful warnings.

Has anyone considered extending dash?

Posted Aug 8, 2009 11:30 UTC (Sat) by marcH (subscriber, #57642) [Link] (1 responses)

> The bash(1) manpage doesn't state which features are standard and which are not,

I never use the Bash's man page. Bash's info manual has a "Features found only in Bash" section and is much better generally speaking. If, like many other people you dislike the basic info reader there are a number of alternatives like for instance "yelp info:bash"

> and the standard itself is not always easy to find (or read, for that matter).

Every time I have a doubt about standard conformance I just google for "opengroup + sh-keyword" and most of the time I just land automagically on a page that answers my doubt. In the worst cases the answer is only a few further clicks away.

Has anyone considered extending dash?

Posted Aug 13, 2009 17:23 UTC (Thu) by fbriere (guest, #4961) [Link]

> Bash's info manual has a "Features found only in Bash" section and is much better generally speaking.

Thanks, that's good to know. (Looking at it, I believe I might have erroneously used pushd/popd myself.)

However, it appears to be a list of generic features, so it's far from a thorough list. While the "Bash POSIX Mode" subsection goes into more detail, I didn't see any mention of, for example, bash-specific expansion patterns like ${foo/bar/baz}.

> Every time I have a doubt about standard conformance I just google for "opengroup + sh-keyword"

Unfortunately, bash (like Perl) has gobs of Google-unfriendly concepts. (Searching the standard for "." was fun...)

whodathunk: '.' searching the current directory is a bashism

Posted Apr 14, 2018 19:00 UTC (Sat) by salewski (subscriber, #121521) [Link] (3 responses)

> As a result, most script maintainers are blisfully ignorant of what the standard requires. (I myself strive to adhere to the standard,

I do the same.

> yet I didn't know until recently that "." searching the current directory is a bashism.)

Say what? I gotta see...

    $ printf 'echo output from saywhat.sh\n' > saywhat.sh

    $ . saywhat.sh
    dash: 108: .: saywhat.sh: not found

    $ . ./saywhat.sh
    output from saywhat.sh

    $ apt-cache policy dash | grep '\*\{3\}'
     *** 0.5.8-2.4 990

Thank you for pointing it out; I had no idea.

whodathunk: '.' searching the current directory is a bashism

Posted Apr 28, 2018 18:51 UTC (Sat) by flussence (guest, #85566) [Link] (2 responses)

I even had bash itself refuse to ". .bashrc" at login recently, and gave up trying to figure out why. The only thing I was doing different was accessing it over mosh instead of ssh, but that doesn't explain why the shell would suddenly be posix-strict.

whodathunk: '.' searching the current directory is a bashism

Posted May 2, 2018 14:13 UTC (Wed) by cortana (subscriber, #24596) [Link] (1 responses)

IIRC bash < 4.4 special-cased the startup process when it detected it was being launched by SSH; perhaps that had something to do with it?

whodathunk: '.' searching the current directory is a bashism

Posted May 5, 2018 16:54 UTC (Sat) by flussence (guest, #85566) [Link]

I was unaware of that... could be, I didn't pay particularly much attention at the time.

A tale of two shells: bash or dash

Posted Aug 6, 2009 9:04 UTC (Thu) by fb (guest, #53265) [Link] (2 responses)

I changed /bin/sh to dash when it was still called "ash". At once it reduced my booting time by more than a third of what it was.

That was probably 5(?) years ago, and the "trick" was then already well known to people reading debian-user. It became even more popular after Nokia did it as well in their first N700 tablet.

I think it bears testimony to Ubuntu's commitment to improving the user experience that they did this change. The fact that so far, AFAIK, they were the only dist that did it, shows IMO the lack of actual focus on desktop usability by most Linux distributions.

A tale of two shells: bash or dash

Posted Aug 6, 2009 10:00 UTC (Thu) by epa (subscriber, #39769) [Link]

Do you remember early Minix, when the standard /bin/sh shell was lean and fast, but with ash available as a more comfortable but bloated alternative for interactive use?

A tale of two shells: bash or dash

Posted Dec 10, 2009 16:51 UTC (Thu) by gvy (guest, #11981) [Link]

(waking up: which year it is, huh? :)

As already mentioned, having script-oriented shell for interactive use is a crime, and a silly one: one can have stripped-down $whatever (e.g. bash or dash) *without* readline support and half the other things as /bin/sh -- but enjoy proper zsh as an interactive chair.

Just in case, ALT Linux has sh and bash different since 2002.

A tale of two shells: bash or dash

Posted Aug 6, 2009 13:38 UTC (Thu) by fbriere (guest, #4961) [Link]

Those that oppose the move simply want a choice, which exists using dpkg-reconfigure dash.

Nobody's taking that choice away. The proposal is to make /bin/sh point to dash by default on new installations. This will still be modifiable later on, and it will not affect any existing installation.

The debate centers around the fact that making dash essential will force its installation on every Debian system, even if it is unused. And since it's quite difficult to make a package un-essential again, this may pose a problem if dash ever falls out of grace, or becomes "too bloated" and gets replaced by posh or what have you.

Korn shell

Posted Aug 6, 2009 13:53 UTC (Thu) by addw (guest, #1771) [Link] (2 responses)

I put a
#!/bin/ksh -u
line at the top of all of my scripts - ensure that I know what I am getting.

Why ksh - well it is the POSIX shell, so more likely to be portable to any non Linux Unix systems.
Ksh also has nice string handling that means that you don't need to use eval, there are other nice things over & above some shells. This is the sort of reason that people like to use bashisms - it does make for faster scripts -- but only if you need to do that sort of thing.

Korn shell

Posted Aug 6, 2009 15:54 UTC (Thu) by tzafrir (subscriber, #11501) [Link]

$ whatis ksh
ksh (1) - the Z shell

Korn shell

Posted Aug 7, 2009 10:36 UTC (Fri) by nix (subscriber, #2304) [Link]

Actually pdksh, used on Linux, has sufficiently many bugs not shared by other ksh implementations (many critical, some such actually documented as never to be fixed in the manpage!) that whenever I want a portable shell script of any complexity I write it in zsh. At least there's one implementation of that and bugs get fixed in it.

shell arithmetic is not a "bashism"

Posted Aug 7, 2009 16:02 UTC (Fri) by vapier (guest, #15768) [Link] (2 responses)

The article lists "shell arithmetic" as a "bashism", but that is obviously incorrect:
http://www.opengroup.org/onlinepubs/9699919799/utilities/...

dash has had a history of not supporting all of POSIX's math requirements (like `v=1; echo $((v))`), but that should be fixed now (if not by dash, then by distros).

shell arithmetic is not a "bashism"

Posted Aug 7, 2009 20:34 UTC (Fri) by branden (guest, #7029) [Link] (1 responses)

It depends on which kind of shell arithmetic you're talking about.

The article's author may have been thinking of:

bash$ if (( 2 + 2 )); then echo yes; fi
yes

ash$ if (( 2 + 2 )); then echo yes; fi
ash: 2: not found

As the bash manpage notes, "This is exactly equivalent to let "expression"."

"let" isn't SUSv3, so (( )) isn't either.

You are probably thinking of:

$ echo $(( 2 + 2 ))
4

Which *is* SUSv3.

shell arithmetic is not a "bashism"

Posted Sep 4, 2009 10:32 UTC (Fri) by vapier (guest, #15768) [Link]

really you just backed up my point. while bash does have arithmetical extensions, the phrase used in the article is wrong. you cant lump "shell arithmetic" in with "let", "source", and "echo -e".

A tale of two shells: bash or dash

Posted Aug 7, 2009 20:46 UTC (Fri) by mennucc1 (guest, #14730) [Link] (1 responses)

I was badly bitten in 2006 by bug 379277; since then I have not liked a lot the idea of Debian switching the defaul shell for scripts to dash.

A tale of two shells: bash or dash

Posted Aug 8, 2009 11:34 UTC (Sat) by marcH (subscriber, #57642) [Link]

> I was badly bitten in 2006 by bug 379277;

"echo" sucks. Use "printf"

Has anybody profiled bash?

Posted Aug 11, 2009 8:55 UTC (Tue) by walles (guest, #954) [Link]

Has anybody profiled bash to see why it's slow? Can bash be fixed?


Copyright © 2009, Eklektix, Inc.
This article may be redistributed under the terms of the Creative Commons CC BY-SA 4.0 license
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds