Does anyone know of any resources that talk about best practices or design patterns for shell scripts (sh, bash etc.)?
Does anyone know of any resources that talk about best practices or design patterns
Share
Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.
Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.
Lost your password? Please enter your email address. You will receive a link and will create a new password via email.
Please briefly explain why you feel this question should be reported.
Please briefly explain why you feel this answer should be reported.
Please briefly explain why you feel this user should be reported.
I wrote quite complex shell scripts and my first suggestion is "don’t". The reason is that is fairly easy to make a small mistake that hinders your script, or even make it dangerous.
That said, I don’t have other resources to pass you but my personal experience. Here is what I normally do, which is overkill, but tends to be solid, although very verbose.
Invocation
make your script accept long and short options. be careful because there are two commands to parse options, getopt and getopts. Use getopt as you face less trouble.
Another important point is that a program should always return zero if completes successfully, non-zero if something went wrong.
Function calls
You can call functions in bash, just remember to define them before the call. Functions are like scripts, they can only return numeric values. This means that you have to invent a different strategy to return string values. My strategy is to use a variable called RESULT to store the result, and returning 0 if the function completed cleanly. Also, you can raise exceptions if you are returning a value different from zero, and then set two "exception variables" (mine: EXCEPTION and EXCEPTION_MSG), the first containing the exception type and the second a human readable message.
When you call a function, the parameters of the function are assigned to the special vars $0, $1 etc. I suggest you to put them into more meaningful names. declare the variables inside the function as local:
Error prone situations
In bash, unless you declare otherwise, an unset variable is used as an empty string. This is very dangerous in case of typo, as the badly typed variable will not be reported, and it will be evaluated as empty. use
to prevent this to happen. Be careful though, because if you do this, the program will abort every time you evaluate an undefined variable. For this reason, the only way to check if a variable is not defined is the following:
You can declare variables as readonly:
Modularization
You can achieve "python like" modularization if you use the following code:
you can then import files with the extension .shinc with the following syntax
import "AModule/ModuleFile"
Which will be searched in SHELL_LIBRARY_PATH. As you always import in the global namespace, remember to prefix all your functions and variables with a proper prefix, otherwise you risk name clashes. I use double underscore as the python dot.
Also, put this as first thing in your module
Object oriented programming
In bash, you cannot do object oriented programming, unless you build a quite complex system of allocation of objects (I thought about that. it’s feasible, but insane). In practice, you can however do "Singleton oriented programming": you have one instance of each object, and only one.
What I do is: i define an object into a module (see the modularization entry). Then I define empty vars (analogous to member variables) an init function (constructor) and member functions, like in this example code
Trapping and handling signals
I found this useful to catch and handle exceptions.
Hints and tips
If something does not work for some reason, try to reorder the code. Order is important and not always intuitive.
do not even consider working with tcsh. it does not support functions, and it’s horrible in general.
Please note: If you have to use the kind of things I wrote here, it means that your problem is too complex to be solved with shell. use another language. I had to use it due to human factors and legacy.