How can I use a dash in printf string?

printf -v args "-x=%s" "$x"
printf "$var"

But it gives an error:

./tmp.sh: line 2: printf: -x: invalid option
printf: usage: printf [-v var] format [arguments]

I know that it's because printf interprets -x as an option, but how to overcome it?

I use printf to create a string that will correspond to command line arguments like -x=xxx -y=yyy -z=zzz. Then I want to call a tool like

eval $tool args

  • 2
    You don't want to use printf at all, as you should be building an array of arguments to pass to tool: foo=(-x xxx -y yyy); tool "${foo[@]}" – chepner Jul 25 '18 at 14:02

printf supports the conventional end-of-options argument --:

$ printf -- '-x\n'
  • 2
    POSIX requires printf to deal with --. – schily Jul 25 '18 at 14:01
  • 1
    Such support is usually indicated by requiring conformance to the Utility Syntax Guidelines, but printf makes no mention of such a requirement. (At least that I could find; I often fail to find things in the place where I expect them.) – chepner Jul 25 '18 at 14:06
  • POSIX gives no permission to disregard the USG for printf. – schily Jul 25 '18 at 14:18
  • dash is not POSIX compliant in many cases. It would e.g. need to support multi byte characters in case it is not run only on a tiny embedded system. – schily Jul 25 '18 at 14:19
  • 2
    @chepner, see pubs.opengroup.org/onlinepubs/9699919799/utilities/…. Standard utilities that do not accept options, but that do accept operands, shall recognize "--" as a first argument to be discarded. – Stéphane Chazelas Jul 25 '18 at 14:26

You could use the end of options (--) argument to have printf treat the dash literally:

printf -v var -- '-x=%s' "$x"


$ x=xxx && printf -v var -- '-x=%s' "$x" && echo $var

Since your printf seems to take options, use a format string to output both the -x and the value of the variable:

printf '%s=%s' '-x' "$x"

To call a tool with a pre-generated command line, don't put the command line arguments into a string. Use set to set the values of $@ instead:

set -- -x="$x" -y="$y" -z="$z"

Then call the tool:

tool "$@"

This will ensure that the tool gets the correct number of arguments, properly quoted, even if one or several of the values, $x, $y, or $z, contains spaces.

Or, using a bash array:

args=( -x="$x" -y="$y" -z="$z" )

tool "${args[@]}"

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.