9

I have a call with a pretty long list of arguments in my shell script:

foo-command \
    --important-argument $ONE \
    --indispensable-flag $ENABLED \
    --an-optional-toggle "will probably be commented out some day" \
    $ARGUMENTS \
    $MORE_ARGUMENTS

Can't I insert comments in this multiline call, can I?

For example, lets say, how can I comment out the --an-optional-toggle line?
How can I add an # in sorted order comment after $ARGUMENTS?

No matter what I try, the octothorp # symbol shadows line continuation backslash \, or vice versa. Any advise?

ulidtko
  • 14,740
  • 10
  • 56
  • 88

3 Answers3

7

No, but you can store the arguments in an array instead. This allows you to both comment out an individual line as well as include interspersed comments.

args=( --important-argument "$ONE"
       --indispensable-flag "$ENABLED"
       # --an-optional-toggle "will probably be commented out some day"
       $ARGUMENTS  # in sorted order
       $MORE_ARGUMENTS
     )
foo-command "${args[@]}"

Note that you will almost certainly want to make ARGUMENTS and MORE_ARGUMENTS arrays as well, so args would end up looking like

args=( --important-argument "$ONE"
       --indispensable-flag "$ENABLED"
       # --an-optional-toggle "will probably be commented out some day"
       "${ARGUMENTS[@]}"  # in sorted order
       "${MORE_ARGUMENTS[@]}"
     )
ulidtko
  • 14,740
  • 10
  • 56
  • 88
chepner
  • 497,756
  • 71
  • 530
  • 681
  • +1 using BASH arrays is the right way than using long multiline command line. – anubhava Aug 27 '14 at 14:16
  • As a side note: this is strictly a Bash-dependent approach. Arrays don't work in older shells a.k.a "`sh`", which may be of importance for someone. – ulidtko Aug 27 '14 at 14:20
  • 1
    If you are concerned about portability, tag your question `sh` instead of `bash`. – chepner Aug 27 '14 at 14:32
  • 1
    It should probably be noted that using an array with `"${ARGUMENTS[@]}"` instead of a plain, unquoted `$ARGUMENTS` variable avoids unwanted pathname expansion of the value. – user2719058 Aug 27 '14 at 19:43
6

Try the backtick comment hack as proposed in an earlier response to the same question.

In your case, this would be:

foo-command \
    --important-argument $ONE \
    --indispensable-flag $ENABLED \
    `#--an-optional-toggle "will probably be commented out some day"` \
    $ARGUMENTS \
    $MORE_ARGUMENTS
Community
  • 1
  • 1
lxg
  • 12,375
  • 12
  • 51
  • 73
  • 2
    Take care that the commented line does not itself contain command substitutions, since they will still be expanded. – chepner Aug 27 '14 at 14:39
1
foo-command $(
    # hello
    printf --important-argument $ONE # free as a bird
    printf --indispensable-flag $ENABLED
    # to comment anywhere we wish
    printf --an-optional-toggle "will probably be commented out some day"
    printf $ARGUMENTS
    printf $MORE_ARGUMENTS
)

It's not perfect: echoing -n is hard because echo interprets it; quotes may be disappeared when you would prefer to keep them, etc. In fact as commenters say below, the quoted string will get mangled; maybe you can work around that, but other answers here are better if you have Bash.

John Zwinck
  • 239,568
  • 38
  • 324
  • 436
  • 2
    If the argument to the optional comment actually contains whitespace, this will not work. – chepner Aug 27 '14 at 14:15
  • 1
    This can be improved. `printf` instead of `echo` will alleviate some problems, including `-n` (and others) interpretation. Command substitution can be inlined and get rid of an extra function definition. – ulidtko Aug 27 '14 at 14:17
  • You guys are right, @chepner's answer is pretty much a better version of what I did here. All hail the bash master. – John Zwinck Aug 27 '14 at 14:21
  • @JohnZwinck, cheer up! Your solution has an advantage of being *portable*, in the sense of compatibility with plain `sh`. – ulidtko Aug 27 '14 at 14:22
  • @ulidtko: Thanks. I wouldn't wish plain `sh` on my worst enemy. I guess it's better than `ed`. :) – John Zwinck Aug 27 '14 at 14:24
  • @ulidtko Portability doesn't matter if it isn't correct. However, I thought I remembered someone telling me that arrays may be added to the POSIX specification. There really isn't a portable alternative to their use in a case like this, short of a truly horrific construction involving `eval`. – chepner Aug 27 '14 at 14:28
  • (Hm, it might be ANSI-style quoting `$'...'` that I heard was under deliberation. But arrays would be useful as well.) – chepner Aug 27 '14 at 14:38
  • 2
    Note that `printf(1)` tries to expand its first argument, so using plain `printf $ARGUMENTS` is not a very good idea. `printf "%s\n" $ARGUMENTS` is better. – user2719058 Aug 27 '14 at 19:40