busybox ash is a very basic implementation of a POSIX compliant shell as specified in the Single UNIX Specification, Version 4 (SUSv4), a (clone of the) successor of the original Bourne shell. In order to work on severely flash/ RAM constrained systems, it implements barely more than the minimum required by SUSv4 (its exact feature set is configurable during busybox' build process to a considerable extent).
The Bourne Again SHell is another successor basing on these principles of being a (mostly-) SUSv4 compliant system shell for interactive and non-interactive uses. As many other GNU tools, it emphasizes the convenience aspects (including interactive usage) and extends beyond the basic feature set mandated by POSIX, making it a superset (which might occasionally diverge from the standard) of a POSIX shell.
This extended feature set easily lulls the user writing (#!/bin/sh
) shell scripts on systems using bash as system shell to assume the feature set of bash would be generally available on all POSIX systems, leading to portability issues ("bashisms") if these scripts are used on systems with different (more limited or standards adhering) POSIX shells used as (non-interactive-) system shell (e.g., all of the *BSD operating systems, the commercial Unices (Solaris, AIX, …) and particularly embedded systems, like e.g. OpenWrt). As a result, any POSIX/ SUSv4 compliant shell script should work fine on bash, dash, pdksh, posh, mksh, busybox ash, but a bash script (incorrectly using a #!/bin/sh
shebang, instead of #!/bin/bash
) will fail spectacularly when executed on a shell not offering these additional (non-standard) features.
For non-interactive uses, especially on -but not limited to- resource constrained devices, bash might be rather on the heavy side, in terms of disk size, memory requirements and startup time, which is a particular concern on lower end systems (especially while booting the system on a sysv like init system, which has to execute between dozens and hundreds of tiny initscripts to boot the system). Because of this, Canonical's Ubuntu (and later followed by Debian) has switched the non-interactive system shell (the shell used for executing #!/bin/sh
'shell' scripts) from bash to a smaller/ more limited/ faster shell (dash, another ash successor) in 2006. This has brought the danger of bashisms into a broader focus, as this exposed the lazy programming in thousands of (particularlly GNU derived) opensource projects.
While you can write shell scripts on a system using bash as /bin/sh
, you should be aware of the common pitfalls and differences between a basic POSIX compliant shell and bash and should test your results on a variety of different SUSv4 compliant shells (e.g. dash, posh, pdksh/ mksh and busybox ash) before using #!/bin/sh
as shebang. If in doubt, use #!/bin/bash
instead (which will execute your script under bash, instead of a generic POSIX shell), obviously bash needs to be installed on the target system for this to work (which is not the case on OpenWrt, so here you really need to restrict yourself to the feature set described in SUSv4). Literature on programming in bash can still be a valuable resource, so are the shell specific chapters of the Single UNIX Specification, Version 4 (SUSv4).