I'm trying to use printf to format some pretty output in a bash script


| This is some output | 

But I've stumbled over some behavior I don't understand.

$ printf "--"

gives me the error:

printf: usage: printf [-v var] format [arguments]


$ printf "-stuff"

results in

-bash: printf: -s: invalid option

So apparently printf thinks I'm trying to pass some arguments while I'm not.

Meanwhile, completely by accident, I've found this workaround:

$ printf -- "--- this works now ----\n"

gives me

--- this works now ----

Can anyone explain this behavior?

  • 1
    See also unix.stackexchange.com/questions/11376/… – manatwork Oct 17 '11 at 11:51
  • Out of intereset, are there any implementations of echo that would fail when doing echo ------------? Most only support -n (no trailing newline), -e (interpret backslash-escaped chars) and possible -E (do NOT interpret them) and do not error out when other option-like arguments are encountered, right? (EDIT: GNU's /bin/echo also supports --help and --version.) – janmoesen Oct 18 '11 at 6:34

The -- is used to tell the program that whatever follows should not be interpreted as a command line option to printf.

Thus the printf "--" you tried basically ended up as "printf with no arguments" and therefore failed.

  • 26
    In other words, to print -- you can run printf -- --. – l0b0 Oct 17 '11 at 12:14
  • 2
    ... and printf -- is the same as printf (you get the same message) – Peter.O Oct 17 '11 at 14:54
  • 3
    Note that printf -- $fmt is not portable. On busybox 1.30.1, printf -- '%s\n' hello yields --. See also: pubs.opengroup.org/onlinepubs/009695399/utilities/printf.html – kelvin Nov 17 '19 at 22:18
  • @kelvin, What? busybox/printf.c#L421 – Alexander Shukaev Apr 26 '20 at 0:11
  • 1
    @AlexanderShukaev My bad, I tested it on LineageOS and now I see that it uses mksh in adb shell instead of busybox. It works normally with busybox printf -- '%s\n' hello. The point about portability still stands though. – kelvin Apr 26 '20 at 3:53

-- is being interpreted as an option (in this case, to signify that there are no more options).

A format string should always be included when using printf to prevent bad interpretation. For your particular case:

printf '%s\n' '-----------------------'
  • what about when you need to do this with a sequence? printf '-%.0s' {1..54} – qodeninja Aug 18 '19 at 18:42
  • 5
    @qodeninja Then you actually do want to use -- :-) printf -- '-%.0s' {1..54} – Chris Down Aug 19 '19 at 14:33
  • @qodeninja printf '\055%.s' {1..54} – jhnc Jul 14 at 16:14

There are differences between printf builtin and /usr/bin/printf, the second one do "what you mean" without these annoying errors.

printf "-----"             # error
printf -- "-----"          # ok
/usr/bin/printf "-----"    # ok
/usr/bin/printf -- "-----" # ok

POSIX provides the option of using octal encoding.

 printf "--"

can become:

printf "\055-"

This is a portable way to avoid the ambiguity of whether -- is being used as a format string or as a marker for the end of options.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.