Jul 19
Tips for learning to program Unix/Linux shell scripts
I’ve been studying shell scripting in more depth recently. Here’s some of the things I found useful on the way.
1) Write your scripts to run on a real POSIX / Bourne Shell compatible sh interpreter first rather than bash or any of the other advanced shells. This improves the portability of your scripts and helps you to clearly learn the differences between the basic shell syntax and the advanced syntax introduced in shells such as bash.
On most Linux systems in recent years /bin/sh is a symlink to bash which has allowed people to ‘leak’ bash syntax in without error. Scripts like this only fail when run on a system that’s using a strict sh like on the FreeBSD or Ubuntu Feisty where /bin/sh is symlinked to ‘dash’ - The Debian Almquist Shell, which is a “lightweight POSIX compliant Bourne shell implementation”. IMO this is a better way to internalize the differences between sh and bash than using tools like ‘checkbashisms’ after you’ve created your script.
Firstly always specify ‘/bin/sh’ in the ’shebang’ line at the top of your scripts:
-
#!/bin/sh
-
-
echo "Beginning of my script"
To see what your /bin/sh is linked to try this:
-
$ ls -l /bin/sh
-
-
lrwxrwxrwx 1 root root 4 2007-05-03 13:09 /bin/sh -> dash
You’ll see that on my system (Ubuntu Feisty) the output at the end of the ls command is ‘/bin/sh -> dash’ which indicates that /bin/sh is linked (->) to dash. If on your system it links to bash do not try to link sh to anything else! If you do you may not be able to boot your system! Instead install the ‘ash’ or ‘dash’ shells and run you script in those directly like this:
-
$ dash myscript.sh
2) Bookmark and read these reference manuals:
- Bourne Shell Manual - Steve Parker’s html version of the original Bourne Shell manual great to check exactly what syntax is available in the real Bourne Shell.
- Advanced Bash-Scripting Guide - The best tutorial on bash with loads of practical examples. The section on ‘tests’ (conditional logic) is particularly good.
- Bash Reference Manual - The actual bash manual. It can be a little difficult to find things in this sometimes so it’s worth getting used to its structure
3) Use shell options to help you debug problems. You can do this either by using the ’set’ command (in bash type ‘help set’ to see usage or ‘man sh’ to view the man page) in your script or by passing the option on the command line as you run your script e.g.
-
$ sh -x bin/myscript
Here are the options I find most useful:
- -x Prints commands and their arguments as they are executed
- -u Treat unset variables as an error when substituting
- -e Exit immediately if a command exits with a non-zero status. Note this should be used with caution as there will be no warning when ths happens, you need to use -x to help discover where the problem is happening
There are loads so it’s worth looking through the list.
4) Use bash to discover syntax errors not highlighted by sh. If you script is failing silently in sh it can sometimes be due to a syntax error. On my system dash isn’t reporting these but I’ve found that explicitly running the script in bash often helps locate the cause of the problem.
5) Consider portability. If you know your script is going to be used across many different systems then it’s worth making sure you are only using commands available in the POSIX standard or on Linux now we can use the ones defined in the Linux Standards Base. See LSB Base - Commands and Utilities for more information.

January 30th, 2008 at 12:12 pm
Can you give some good books on shell scripting.
January 31st, 2008 at 12:49 pm
Umm, not really. I haven’t bought any books on the subject so I can’t say. I just use the online resources I linked to in the main article.
However, I have heard good things about some of the O’Reilly books.
February 1st, 2008 at 12:46 pm
Thanks for the post.
Nice research on ubuntu and java.