The answer here is contextual. You want to be able to annotate long lines of parameters and also long complex pipelines, and sadly the syntax does not work the same way.
But there is a 3-step process that can let you comment almost anything in detail, without the subshell overhead of `#...`
or the very complicated quoting land-mines of ${IFS#...}
:
Put everything into a function so you can use local
variables
You're writing a complex enough shell script to have functions anyway, right? We need to give everything names in order to use the named-array syntax, but we also don't want to pollute the global shell namespace, so tidy them away into local variable declarations.
Put long commands into arrays
Arrays don't need \
line continuations, so you can use comments as normal, like this:
local x=(
"command-name"
# here's the command
"argument" # and here's the first arg
)
Put pipelines after all arrays have been defined
If a redirection is complex, you may want to explain it, but if you have a long list of parameters it might get in your way. So use a couple of short-named local
vars that will be short enough to fit your comments, then use redirections or pipelines to break up the lines, not backslashes:
"${x[@]} | # here is my first command
"${y[@]} | # and here's the second one
...
That way the redirection can never get so long that your comments won't fit; you get to choose those variable names, and because they're local
you don't need to make them unique for your whole script.
Put it all together
When you get it all together, it looks like this:
f() {
local produce_text=(
echo
# I'm echoing
"first argument"
# newline!
'
'
# Here's the first arg.
"second argument"
# Here's the second.
)
local number_lines=(
cat
# I'm concatenating
-b
# with numbered lines
)
"${produce_text[@]}" |
# explaining the pipeline
"${number_lines[@]}" \
2>&1
# done
}
N.B.: Everything in this answer was also checked with zsh
, so while it (probably?) won't work in POSIX sh
, it's not entirely bash
-specific.