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?
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.
According to the man page for printf
, there are two ways it is used:
printf FORMAT [ARGUMENT]...
printf OPTION
The options are specified using two dashes followed by the option name.
--help
display this help and exit
--version
output version information and exit
So when you specify printf "--"
, the printf
command thinks you are using the command with an option.
Since the printf
command allows the standard set of options, you can use the --
option to delimit (end) the option list and then use the format of "--"
. See the common options man page:
--
Delimit the option list. Later arguments, if any, are treated as operands even if they begin with-
. For example,sort -- -r
reads from the file named-r
.
printf -- "--"
As a side note for others, you may need to use single quotes rather than double quotes with some format specifiers in order to prevent the shell from doing substitution on the command line before invoking printf
and passing the modified command line to it.
--
is special separator for shell commands! Try:printf -- "--"
– F. Hauri - Give Up GitHub Commented Jan 22 at 20:59--
inman bash
andman sh
! – F. Hauri - Give Up GitHub Commented Jan 22 at 21:02printf "%s\n" --
also works. The first argument should be the format string. – Barmar Commented Jan 22 at 21:08-
, not U+2013 EN DASH–
. – wjandrea Commented Jan 22 at 21:28