How to add comments to multiline commands in shell scripts

Published:

You’re writing a shell script, and you’ve got a long command that you’re splitting up over multiple lines, but you don’t expect yourself or anyone else to remember what each of those commands means.

How about adding a comment above each command? Well… this unfortunately doesn’t work:

# my awesome bash script
rsync -avz ⧵
  # don't preserve owner, don't preserve group
  --no-o --no-g ⧵
  source ⧵
  destination

The backslash merges the lines, and a comment in the middle of the command would kill the remainder of your command. We can see this happening with a simple echo:

$ echo "one" #two "three"
one

$ echo "one" "three"
one  three

link iconMultiline commands using command substitution

To get echo to ignore the comment in the simple demonstration above, we can use command substitution:

$ echo "one" `#two` "three"
one  three

Command substitution ensures that #two is executed in a subshell and returned to echo before it is executed.

This means we can do the same in our multiline command:

# my awesome bash script
rsync -avz ⧵
  --no-o --no-g `# don't preserve owner, don't preserve group`source ⧵
  destination

link iconUsing arrays

An alternative is to build our command using an array:

rsync_args=(
  -avz
  # don't preserve owner, don't preserve group
  --no-o --no-g
  source
  destination
)

rsync "${rsync_args[@]}"

A benefit of this approach is that it’s easy to comment out specific arguments, which we can see is not possible from our first example.

Arrays in shell scripts are pretty versatile - here’s an excellent guide on how to use bash arrays.

Enjoy!