command dispatch via bash ${array[@]} notation, oh my!

“Programs must be written for people to read, and only incidentally for machines to execute.”
— Harold “Hal” Abelson

This highfalutin aphorism applies from the most cerebral application programming language of your choice, right down to the humble (or not-so-humble) bash script. Love or hate them, bash scripts are the primary method of launching processes on Linux in many settings. (You may well run a fancy-pants orchestrator, but when that calls into your app it is 50/50 if it calls a bash wrapper script or not.) I think of bash as a tool for writing things which set the execution context and run the main program, and no more than that.

All too often one sees examples on the web of people saying “launch this program under docker via this bash one-liner”, and then they proceed to demonstrate with a command-line which goes on and on for ages and never seems to stop, very much like this sentence.

Sometimes people are considerate enough to lay out their example over several lines, all but the last of which has a trailing back slash character “\” to indicate to bash that the command continues on the next line. Here’s a contrived example of what I mean.

#! /bin/bash

/usr/bin/java \
    -XX:+UnlockExperimentalVMOptions \
    -XX:+PrintFlagsFinal \

Unfortunately there are a few problems with this notation in the real world. (The above example is not the real world.)

  • It does not allow for individual lines to be commented out.
  • It does not allow for any characters after the \, which means that
    • it does not allow for explanatory comments to be added at the end of a line
    • invisible (depending on the text editor) space characters can creep in after the backslash and cause weird and annoying error messages

Because of the above, this syntax looks and feels brittle. In the real world (that thing again) one often wishes to comment and uncomment command line options when experimenting with a new configuration. Never fear, bash array notation to the rescue…

#! /bin/bash

argv=( /usr/bin/java )
argv+=( -XX:+UnlockExperimentalVMOptions )
argv+=( -XX:+PrintFlagsFinal )
argv+=( -version )


This solves all three of the original problems, but it looks a bit clumsy, what with the repeated mention of the variable name and brackets on every line. All I’m doing is enumerating the arguments to a command for goodness’ sake.

Happily, we can remove the += stuff and most of the brackets, make a single array, and get straight to the point, viz.

#! /bin/bash


        -XX:+UnlockExperimentalVMOptions  # trailing comment
        # -XX:+PrintFlagsFinal




If you’ve ever had cause to tangle with the joy that is “” on the installation of an Atlassian application, I’m sure you’ll appreciate the clarity of the above syntax. Yes, I know they have to run under other systems like FreeBSD or Solaris, which most likely don’t have bash. I’m talking about in-house stuff, where the toolset is well-known.

Leave a Reply

Your email address will not be published. Required fields are marked *