Archive for General programming

Unix shell scripting — code smells

I develop and maintain a bunch of bash shell scripts for my Raspberry Pi (e.g. downloading of files from list of urls, monitoring physical gpio power off switch etc.). I have to admit I did not pay close attention to designing them perfectly, I just wanted to get the job done. However, even in such a simple cases I have experienced myself kind of technical debt when something suddenly went wrong. It is always good to follow good design principles. Here I mean avoiding unnecessary dependencies between software modules. Even in such simple programs.

These are my quick observations of what to do and what not to do when writing either shell scripts or interpeter scripts under Unix/Linux environment.

  • DO NOT USE DOT CHARACTER in script’s code. Use variables, assign them a value once and then refer to them in the code. Relying on external assumptions that script will be executed in certain directory is bad and will hurt. It is extremely likely you will forget the (in fact, unnecessary) requirements when executing script elsewhere, e.g. from cron.
  • If you absolutely have to refer to some file located in the same directory as the script itself, consider writing another script whose solely purpose is to change the directory to meet target’s expectations and then immediately execute it. Although it would be strange to write shell script to execute another shell script, this technique can be used with other interepreted languages e.g. Python or Perl scripts.
  • DO NOT USE TILDE CHARACTER in script’s code. It has not obvious expansion rules. For instance, it works at the beginning of the word, but not in the middle. That also means, it is very likely to forget the rules and have the tilde character not expanded in location where it is expected to. Use the value of HOME variable and expand it in one of traditional ways.

Little semantic pitfall of try..finally

This time I would like to point out the behaviour, that should be absolutely clear to any C# developer. When an exception is thrown inside try..finally block (without catch), and consequently in the scope of a using statement, it is bubbled up to the containing scope, rather than handled in any way. It implies that try..finally without catch has in fact nothing to do with exception handling.

I have already come across learning materials that suggest the otherwise. Let’s have a look at [1] (my own translation from Polish):

With a using clause we end up having code which is proof against exceptions

and [2]:

A finally block can be used to handle any exception

In my opinion the fact, that in the very case of try..finally apart from catch an exception is simply thrown out of the scope, is not stressed enough in the literature and claims like these above can be misleading.

Going a little bit further, I consider this as a little semantic pitfall in the language. When we think of a try statement, we immediately recall exception handling mechanism. However this time this is not the case. Maybe other languages have better (i.e. more meaningful) way of expressing the intent of a code being executed at the end of a scope. Have a look at scope(exit) and scope(failure) instructions in D language in [3].

[1]. Polish magazine “Programista”, issue 6/2013 (13) p. 26

[2]. “Programming in C#, A primer, second edition”, chapter 18.8

[3]. Three Unlikely Successful Features of D