I can't print -- (two endashes) characters using bash printf
function. When I execute the following code
printf "--"
I get the error message saying
printf: usage: printf [-v var] format [arguments]
Why is this happening? And how can I print them?
Use printf -- "--"
(or printf -- --
; the quotes are not needed in this case).
printf
is a built-in command in bash, so a plain printf
executes the built-in command rather than the system /usr/bin/printf
. The bash man page (for GNU bash 3.2.57 on macOS 15.2) says “Unless otherwise noted, each builtin command documented in this section as accepting options preceded by - accepts -- to signify the end of the options.” Since printf
accepts an option starting with -
(it accepts a -v
option), it accepts --
to signify the end of the options.
Thus the first --
in printf -- "--"
tells printf
to stop interpreting arguments as possible options, so the next argument must be the format string.
The bash man page says the syntax for printf
is:
printf
[-v
var
]format
[arguments
]
where […]
denotes something optional. If this were the true syntax for printf
, then clearly the --
in printf --
must be the format
, because it is not the -v
. So the above is not the actual syntax for printf
. It is modified by the earlier text that says commands accept --
to signify the end of options.
Similarly, printf -x
would take -x
as the format string, but instead it yields an error, “-x: invalid option”. In this case, I do not see any text in the bash man page that says this can happen. (This is a deficiency in the bash documentation; it fails to specify the actual behavior of the printf
command, and likely others.)
What is happening here is that -
is a ubiquitous character for introducing “switches”1 in Unix commands (whether standalone or built into a shell). So, while it is not documented, the true syntax of many commands is that arguments beginning with a -
are interpreted as a user attempt to specify a switch. Then, if the switch is not recognized by the command, an error is issued. However, if we execute printf -- -x
, then --
says not to consider following arguments as possible options, so -x
is taken as the format string, and “-x” is printed.
1 Switches are arguments that specify settings or introduce supplementary information to a command, rather than being the main things the command operates on.