I have the following printf function:

$ printf '%s %s %s\t%s\n' 100644 blob 8e1e f1.txt 100644 blob 9de7 f2.txt | git mktree

Can anyone please explain what it produces and why? I expected to have equal number of formatting options %s for each argument string but I have a lot more arguments strings here.

  • Run help printf to see the shell's built-in documentation for its printf builtin. – Peter Cordes Aug 19 '17 at 15:43

The format is reused as many times as needed to display all arguments. If there are too few arguments, the missing arguments are treated as empty strings.


Here is an example of a format that specifies two arguments but only one is provided:

$ printf '%s ; %s ;\n' a
a ;  ;

Here is the same format, this time provided with one too many arguments:

$ printf '%s ; %s ;\n' a b c
a ; b ;
c ;  ;

Here is the example from the question in which the format expects four arguments. Since eight arguments are provided the entire format is used twice:

$ printf '%s %s %s\t%s\n' 100644 blob 8e1e f1.txt 100644 blob 9de7 f2.txt
100644 blob 8e1e        f1.txt
100644 blob 9de7        f2.txt


From man bash:

The format is reused as necessary to consume all of the arguments. If the format requires more arguments than are supplied, the extra format specifications behave as if a zero value or null string, as appropriate, had been supplied. The return value is zero on success, non-zero on failure.

  • thanks, can you please show how this reuse works in my particular case? – Maxim Koretskyi Aug 19 '17 at 5:56
  • @Maximus Yes, sure, I just added that example to the answer. – John1024 Aug 19 '17 at 5:59
  • 1
    got it, thanks a lot for you elaborate answer! good luck – Maxim Koretskyi Aug 19 '17 at 6:06
  • 2
    And the format is used at least once even if there's no argument, which is annoying in cases like printf '* %s\n' "$@" which you have to work around with [ "$#" -eq 0 ] || printf '* %s\n' "$@". – Stéphane Chazelas Aug 19 '17 at 8:50
  • The zero argument case is a bit of a pain. but another way is to always have at leas tone argument. For example a solution to the last comment... printf "'%s' " "$0" "$@" – anthony Jul 23 '19 at 7:49

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.