I want to write bash scripts that are as self-documentary as possible.

I had an idea that when I execute software with lots of flags, I wanted to split the command into multiple lines, and add a comment at the end of each line, telling what the flag does (info from a man page), like so:

bwa aln \
-n $n \ # -n max #diff (integer) or missing prob under 0.02 err rate (float) [0.04]
-o $o \ # -o maximum number or fraction of gap opens [1]
-e $e \ # -e maximum number of gap extensions, -1 for disabling long gaps [-1]
-i $i \ # -i do not put an indel within integer bp towards the ends [5]
-d $d \ # -d maximum occurrences for extending a long deletion [10]
-l $l \ # -l seed length [32]
-k $k \ # -k maximum differences in the seed [2]
-m $m \ # -m maximum entries in the queue [2000000]
-t $t \ # -t number of threads [1]
-M $M \ # -M mismatch penalty [3]
-O $O \ # -O gap open penalty [11]
-E $E \ # -E gap extension penalty [4]
-R $R \ # -R stop searching when there are >integer equally best hits [30]
-q $q \ # -q quality threshold for read trimming down to 35bp [0]
-f $f \ # -f file to write output to instead of stdout
-B $B \ # -B length of barcode
-L $L \ # -L log-scaled gap penalty for long deletions
-N $N \ # -N non-iterative mode: search for all n-difference hits (slooow)
-I $I \ # -I the input is in the Illumina 1.3+ FASTQ-like format
-b $b \ # -b the input read file is in the BAM format
-0 $0 \ # -0 use single-end reads only (effective with -b)
-1 $1 \ # -1 use the 1st read in a pair (effective with -b)
-2 $2 \ # -2 use the 2nd read in a pair (effective with -b)
-Y $Y \ # -Y filter Casava-filtered sequences
-prefix $prefix \ # -prefix Prefix
-inputfile $inputfile \ # -inputfile Input file (FastQ format)

The problem is that I can not have anything after the \ character (that tells bash that the command continues on next line), and neither can I have the "\" at the end of the line, because then it is treated as part of the comment.

Anybody knows a way to do this, or something similar?

  • 1
    Makes it very hard to read! What's wrong with having multi-line comments before the command? – gawbul Sep 6 '13 at 18:58
  • I have a quite specific use case here, where I want to show how a command is built up (I maybe have to make a video of this :) ): As you select things in a wizard, the "$[var]" part gets replaced. I don't have much screen estate for the command, so making it double as high, by putting the list above, will be too much. I also find it very helpful, when you have that many command line options, to have the comment absolutely adjacent to where it is set. – Samuel Lampa Sep 7 '13 at 6:59

You can evaluate comments before the slash, simply generating empty strings for comments which won't affect your script:

bwa aln \
-n $n `# -n max #diff (integer) or missing prob under 0.02 err rate (float) [0.04]` \
-o $o `# -o maximum number or fraction of gap opens [1]` \
  • 1
    that's distracting and doesnt follow standard programming practices for comments, regardless of language. put the comment on its own line. because it inserts a comment by using code you should technically be commenting the additional code which is extra work that could have been avoided by investing in the comments instead. – Joshua K Sep 6 '13 at 18:00
  • 5
    I may be wrong, but aren't you effectively spawning a subshell with every 'comment'? – Bob Sep 6 '13 at 18:15
  • +GoodTimeTribe: I would disagree. It's like saying Python docstrings are distraction, ... – Soheil Hassas Yeganeh Sep 6 '13 at 23:55
  • +Bob: Yes it clones the shell that immediately returns. – Soheil Hassas Yeganeh Sep 7 '13 at 0:20
  • @Soheil – you need to reply with @, not a + – slhck Sep 7 '13 at 9:29

I suggest using multiple lines to comment the code before the command. like

 # this command uses multiple parameters
 # it requires 4 parameters and none are optional with no defaults
 # parameters used : 
 # -q              name of the file
 # -b              size to truncate
 # -n              new location
 # -r              recursive

One option is to construct your command in pieces so you don't have to worry about line continuation:

cmd='date'                # run the date program
cmd=${cmd}' -d 20130905'  #  for this date
cmd=${cmd}' +%s'          #  with output in this format
echo $cmd                 # review the command
eval $cmd                 # run the command
  • Works too, although slightly harder to read. Thanks for the tip though! – Samuel Lampa Sep 6 '13 at 16:56
  • while i kind of like this, because it's flexible and has flow and additional logic, i feel it puts work into coding when it could've just been commented with grace and style instead. – Joshua K Sep 6 '13 at 18:02
  • This will not work for any arguments that actually contain spaces. Replace '20130905' with '3 days ago' to see what I mean. – chepner Sep 9 '13 at 13:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.