In your example, it worked correctly "by chance". The reason that is that
- you have provided only one argument to
echo
, and
- you have quoted your variable as is recommended.
That means that echo
sees only one string as command-line argument, which is -n Hello
, including the space in between the "words". Now, echo
(well, some echo
s) is programmed such that it recognizes -n
as an option, but not the string -n<space>Hello
, so it will assume that this is an operand - i.e. a string you want to print "as is" (well, possibly with \
sequences expanded).
Had you used
echo $var
without quotes instead, and with the default value of $IFS
, then $var
would have been split at the space, and echo
would have seen two arguments: -n
- which it will interpret as an option - and Hello
.
This means that in this case, correctly quoting your shell variables was a remedy against involuntarily running into a situation where echo
interprets an operand as an option.
However:
Remember that the example in your linked source was printing a list of files via "glob expansion" (*.zip
), where the variable must be used unquoted, so it is not always possible to use that guard.
Quoting the variables can only help in cases where word-splitting would lead to echo
seeing an option-argument. If the argument to be printed is a single -n
to begin with, quoting cannot help you.
Consider e.g. a case where you have collected an array of strings that you want echo
to print, and one of the strings happens to also be an option argument to echo
:
arguments=( "-n" "Hello" )
Then, even if you correctly quote the variable, as in
echo "${arguments[@]}"
the first token echo
sees will still be -n
which it interprets as option, rather than an operand.
The same is true if you simply have several variables as arguments to pass to echo
, and the first one turns out to be or start with -n
. Here, too, quoting the variables cannot help you.
In the general case, even quoting will not help you if a program accepts arguments in the form -oValue
.
As a hypothetical case, take a program my_formula_renderer
that typesets mathematical formulae and that accepts an option parameter -sfontsize
. Then, imagine you want to typeset the formula -sqrt(a^2 + b^2)
, as in
./my_formula_renderer "-sqrt(a^2+b^2)"
If your program doesn't have a --
specifier that ends options parsing, it will think that you tried to typeset "nothing" with a font size of qrt(a^2+b^2)
, rather than the above formula with the default font size.
It wouldn't even help in cases where you have explicit space between the -s
and the further formula elements, as in "-s +2t +u^2"
; it might simply mis-interpret this as a "font size" of +2t +u^2
with leading space (see e.g. this question where this became a problem).
The same is true if a program accepts "clustering" of single-letter options.
As noted by @Stéphane Chazelas, echo
for example could interpret a string -neEenennne
as a concatenation of the options -n
, -e
and -E
, so trying to print that string via echo
could fail/behave in an unexpected way.
Beside option processing, echo
(some echo
s, including bash
's when the xpg_echo
option is enabled which it is by default in some builds) does expand \n
, \\
, \b
and so on into a newline, backslash, backspace character, so can't be used to output verbatim strings that may contain backslashes.
TL/DR
The key point is the term "absolutely" in the source you quoted, and the fact that it refers to echo
specifically. In most cases, echo
will be fine. But if you start relying on that blindly, there will (sooner rather than later) be the situation in which echo
, or indeed another, more critical program you call, inadvertently mis-interprets something you intended to be an "operand" parameter as an "option" argument, usually when you pass it as a shell variable.