3

I accidentaly wrote:

printf "here: %s $d\n" "${line:0:32}" "${#line}"

and got:

here: /home/gsamaras/Bash/libs/goodLib 
here: 103 

Why?

Of course I meant to say %d, but I don't understand this behavior in the mistake I made. I would probably expect it to print "here: /home/gsamaras/Bash/libs/goodLib $d", like it would do in C... I couldn't find a duplicate or something on that, thus the question.

gsamaras
  • 71,951
  • 46
  • 188
  • 305
  • @Biffen I am fan of a string is double quotes and a character with single quotes paradigm followed in C and C++, but I see your point, thanks for the tip! RockyLi, I see, but still it's not clear why I get "here" twice... – gsamaras Dec 13 '18 at 14:40
  • 1
    @gsamaras Not to drag this out, but C and Bash are different languages, and single and double quotes have different meanings, respectively, in the two. I wouldn’t generally recommend migrating paradigms between languages like that. – Biffen Dec 13 '18 at 14:44

2 Answers2

6

Before the string "here: %s $d\n" is passed to printf, parameter expansions are performed by the shell. In this case $d is expanded to an empty string.

If you used single quotes around the string, or backslash-escaped the $, then you would see $d in the output.

Since you only have one format specifier in your string (%s) and passed two arguments after the format string, you end up with two lines of output:

The format is reused as necessary to consume all of the arguments.

(from man bash in the printf section).

Tom Fenech
  • 72,334
  • 12
  • 107
  • 141
5

First step, the shell performs variable expansion. Since there's no variable $d, it's replaced with an empty string. After variable replacement it's as if you'd written:

printf 'here: %s \n' /home/gsamaras/Bash/libs/goodLib 103

Now why does it print here: twice? When printf is given more arguments than format specifiers it repeats the format string, looping extra times until it's consumed all of its arguments. Since you have a single %s but two extra arguments it loops twice. It's as if you had written:

printf 'here: %s \n' /home/gsamaras/Bash/libs/goodLib
printf 'here: %s \n' 103

That is why you get two lines of output.

John Kugelman
  • 349,597
  • 67
  • 533
  • 578