Bash and KornShell offer features that are more powerful, and often, more efficient than Bourne Shell. Yet, I constantly see back tics (accent graves), instead of the easier to read format of $(…). I see the use of the expr command for math calculations in stead of (( … )). Even higher on the list of common sins is the use of [ … ], instead of [[ … ]]. It is my contention that the blame lies on introductory books and courses, which change the title to Bash Shell Programming, or KornShell Programming, but are nothing more than warmed-over Bourne Shell courses. So whey not use Bourne Shell syntax? After all, isn’t Bourne Shell the standard UNIX shell?
With the release of Unix System V Release 4 (SVR4), Bourne Shell was on the way out. The standard shell was KornShell, and Bourne Shell (sh) was often a hard link to ksh on UNIX Systems. The day GNU applications became a standard part of Linux is the day that Linux and bash became bound together. On many Linux distros, sh is a symbolic link to bash. The links exist for backwards compatibility to old scripts that have the shbang line as #!/bin/sh. New scripts do not need to be backwards compatible to Bourne Shell, with exceptions noted later in this post.
The statement [[ $var1 == $var2 ]] works in ksh/bash, even when either or bothe variables are null. The Bourne Statement [ $var1 = $var2 ] fails with a missing argument error if either variable is null. The simple solution to this was to always quote variable so that the statements reads [ “$var1” = “$var2” ]. While this makes programming easier, there is even a more compelling reason to use [[ … ]]. The Bourne Shell [ … ] is actually an alias for the test command. In both ksh and bash, test is a built-in command, but [[ … ]] is treated as part of the shell syntax and not a command. If you were running under Bourne Shell, test would be a stand-alone command. These differences impact on performance. Being a part of the syntax is faster than a built-in, and far faster than a stand-alone command.
After 30 years of working with UNIX, expr is still a painful command to use. expr is not a built-in command for any shell. Conversely, the let command, with the (( … )) as a alternate syntax, is a built-in command for both bash and ksh. Again, we have a performance gain, and a much more powerful command. Yet, the expr command is often taught in a shell programming course, but not the let command. Time for us to let go of Bourne Shell.
I cannot count how many times I have mistaken a back tic for a single quote. In many fonts there is not a lot of difference between ` and ‘. Determining which character it is by context is a waste of time and energy. It is far easier to use the $( command ) syntax.
To me awk and sed are basic commands in my toolbox. Yet, I am going to explore whether shell has replaced these commands. As shells gain more features are we changing the UNIX tradition that shell was the glue that tied multiple commands together. Are the days of what used to be called UNIX plumbing with pipes and filters coming to an end? We will see.
Before ending this post, we need to answer the question of whether Bourne Stell still has a purpose. Busybox combines tiny versions of common UNIX utlities into a single exectutable. Busybox uses Bourne Shell as its shell. Busybox is often used in the initial boot image, and in embedded devices. Even though you use a shbank of #!/bin/sh, you are still invoking bash with it supposedly running with only Bourne Shell syntax. Almost is the keyword, there is bash syntax that works but isn’t valid Bourne Shell syntax. To avoid these problems, you can use dash as the default /bin/sh. Dash stands for Debian Almquist Shell. The Almquist Shell (ash) is a clone of SVR4 Bourne Shell, and its code comprises the shell code in Busybox.