This question already has an answer here:
There are 4 bash snippets below. I call them with ./script.sh a b c
for arg in $@; do
echo "$arg"
done ## output "a\nb\nc"
for arg in "$@"; do
echo "$arg"
done ## output "a\nb\nc" -- I don't know why
for arg in $*; do
echo "$arg"
done ## output "a\nb\nc"
for arg in "$*"; do
echo "$arg"
done ## output "abc"
I don't know what is the exact difference between $@
and $*
,
and I think "$@"
and "$*"
should be the same, but they are not. Why?
Difference between $* and $@ is::
"$*" All the positional parameters (as a single word) *
"$@" All the positional parameters (as separate strings)
If you pass three command-line arguments given to a bash script to a C program using ./my_c $@,
you get the result
ARG[1] == "par1" ARG[2] == "par2" ARG[3] == "par3"
If you pass three command-line arguments given to a bash script to a C program using ./my_c $*,
you get the result
ARG[1] == "par1 par2 par3"
If you have a script
foo.sh
:and call it with:
it's equivalent to:
Without the quotes, they're the same:
would be equivalent to:
This matters in shell scripts: for example the script testargs.sh
If this script is executed as
/tmp/testargs.sh a b c 'd e'
, the results are:Thus, if number of arguments are to be preserved, always use "$@" or iterate through each argument using the
for i in $(seq 1 $#)
loop. Without quotes, both are same.