0

The following command prints foo bar, as expected:

sh -c 'printf "$@"' -- "foo bar"

However, when called with foo and bar as separate arguments, it only prints foo:

sh -c 'printf "$@"' -- foo bar

(sh and bash have the same behavior here)

This indicates to me that the expression "$@" is turned into multiple parameters, leading to a call of printf foo bar, instead of printf "foo bar".

  1. Why is this the case? I thought that quotes denote a single string?
  2. How can i change the sh -c command to get the desired behaviour (printf "foo bar") when passing multiple arguments?
ChrisB
  • 1,540
  • 6
  • 20

1 Answers1

1

Why is this the case?

Because $@ is special.

I thought that quotes denote a single string?

Not in the case of $@.

How can i change the sh -c command to get the desired behaviour (printf "foo bar") when passing multiple arguments?

You can use "$*" to join arguments with space (first character from IFS).

From https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_05_02 :

2.5.2 Special Parameters

@
[...] When the expansion occurs within double-quotes [...] the initial fields shall be retained as separate fields [...]

ChrisB
  • 1,540
  • 6
  • 20
KamilCuk
  • 120,984
  • 8
  • 59
  • 111
  • Thank you for the documentation link, that's exactly what I was looking for. Since I'm a little out of depth here, could you clarify one additional thing for me: Would there any difference between `$@` and `"$@"` in this context then? – ChrisB Apr 25 '23 at 11:52
  • Regarding my previous comment: figured it out myself. With `$@`, the individual fields will undergo further field splitting, with `"$@"` they won't. So `"$@"` is correct and necessary for forwarding args. (https://www.gnu.org/savannah-checkouts/gnu/bash/manual/bash.html#index-_0040) – ChrisB Apr 25 '23 at 12:14