-1

I am aware the $@ gives the value of all arguments passed. Suppose if the arguments passed are a, b, "c\ d" and if I print them one by one like:

    #!bin/bash
    for i in $@
     do
     echo $i 
     done

then the output is:

a
b
c
d

and not

a
b
c d

why does it only work if i replace $@ with "$@"? I wish to know the rules behind this. Is "$@" considered as string?

Hold My Stack
  • 45
  • 1
  • 6
  • 1
    It's all in [the docs](https://www.gnu.org/software/bash/manual/html_node/Special-Parameters.html), explicitly. – Ruslan Sep 14 '20 at 07:22
  • 1
    Lesson -- always quote your variables... – David C. Rankin Sep 14 '20 at 07:24
  • Does this answer your question? [When to wrap quotes around a shell variable?](https://stackoverflow.com/questions/10067266/when-to-wrap-quotes-around-a-shell-variable) – Aserre Sep 14 '20 at 07:56

1 Answers1

0

Here's an example to make it clear

shell program file

# case 1
for i in $@;
  do echo $i
done

# case 2
for i in "$@";
  do echo $i
done

When executed this is the output

$ bash  p1.sh a b "c d"
a
b
c
d
a
b
c d

What happens is that the bash shell that is invoking, the interactive shell first splits the parameters into tokens. Next the quotes are removed ( see https://www.gnu.org/software/bash/manual/html_node/Quote-Removal.html#Quote-Removal )

What is passed to the program p1.sh is this quoteless list of tokens

In the first case what is really happening is

for i in a b c d;

in the second case

for i in "a" "b" "c d";

The third token gets to the program as cSPACEd. I'm writing the literal space character (ASCII 0x20) as SPACE

But unless the quotes are used to interpolate it the SPACE is seen by the command as a separator between tokens and so cSPACEd becomes a pair of tokens instead of one token

Vorsprung
  • 32,923
  • 5
  • 39
  • 63