In one of our earlier articles, we saw the different positional parameters in a shell script. We discussed about the positional parameter $*. There is one more positional parameter, $@, the definition of which is also the same as $*. Let us see in this article the exact difference between the parameters $* and $@.
First, let us write a simple shell script to understand $@:
$ cat cmd #!/usr/bin/bash echo "The total no of args are: $#" echo "The \$* is: $*" echo "The \$@ is: $@"On running the above program with some command line arguments:
$ ./cmd 1 2 3 The total no of args are: 3 The $* is: 1 2 3 The $@ is: 1 2 3As shown in the above output, both the $* and $@ behave the same. Both contain the command line arguments given.
Let us now write a script which exactly shows the difference:
$ cat cmd #!/usr/bin/bash echo "Printing \$* " for i in $* do echo i is: $i done echo "Printing \$@ " for i in "$@" do echo i is: $i doneNow, on running the above script:
$ ./cmd a b "c d" e Printing $* i is: a i is: b i is: c i is: d i is: e Printing $@ i is: a i is: b i is: c d i is: eIn the above example, we write a for loop and display the arguments one by one using $* and $@. Notice the difference. When we pass the command line argument in double quotes("c d"), the $* does not consider them as a single entity, and splits them. However, the $@ considers them as a single entity and hence the 3rd echo statement shows "c d" together. This is the difference between $* and $@.
I'm just a n00b, but here goes.
ReplyDeleteI got 4 different result, depending if I quoted $* or $@ in the for loop:
script cmd2 running:
>cmd2 1 2 3 4 5 "6 7 8" 9
Printing $*
i is: 1
i is: 2
i is: 3
i is: 4
i is: 5
i is: 6
i is: 7
i is: 8
i is: 9
Printing $@
i is: 1
i is: 2
i is: 3
i is: 4
i is: 5
i is: 6
i is: 7
i is: 8
i is: 9
Printing "$*"
i is: 1 2 3 4 5 6 7 8 9
Printing "$@"
i is 1
i is 2
i is 3
i is 4
i is 5
i is 6 7 8
i is 9
script cmd2 listing:
#! /bin/bash
## No quotes $*
echo "Printing \$* "
for i in $*
do
echo i is: $i
done
## No quotes $@
echo "Printing \$@ "
for i in $@
do
echo i is: $i
done
## Quoted "$*"
echo "Printing \"\$*\" "
for i in "$*"
do
echo i is: $i
done
## Quoted "$@"
echo "Printing \"\$@\" "
for i in "$@"
do
echo i is $i
done
exit
$* if quoted will always give the entire command line argument list as a single argument.
ReplyDelete$@, if not quoted, will behave like $*.