Question about argument parsing in scripts

Hello all, I am relatively new to linux and bash scripting. I have what seems to be a simple question but I'm having trouble finding the answer.

The question is what is the difference between the variables $@ and $*. I've seen them both used in the same context, and I've tried a number of different scripts to determine the difference but they both seem to do the exact same thing.

Any help would be greatly appreciated. Thanks in advance.

"$@" when used in double quotes, preserves the quoting from the command line, $* does not. A simple script that you can write to show this is:

#/usr/bin/env ksh

for x in "$@"
do
        echo $x
done

echo "==========================="
for x in "$*"
do
        echo $x
done

Executing it with differently quoted tokens on the command line you get this output:

>: t25 now "is the time" for all "good men"
now
is the time
for
all
good men
===========================
now is the time for all good men

t25 is the script name that I used, >: is my prompt.

If you use $* without the quotes, you get each word without regard to the quoting on the command line:

now
is
the
time
for
all
good
men
1 Like

Awesome, thank you for the response. I noticed something else with that output as well. You used the same loop to print out the arguments yet $@ printed all the arguments on separate lines and $* printed them all together. Just curious as to what the reason is for that. It must have something to do with the for loop since if you do the same loop without quotes around the variables, they both print the arguments on separate lines.

Edit: After re reading your post it seems that we're talking about the same thing. Would you be able to explain the reason that happens?

Thanks again.

The expansion of the contents of "$@", "$", and $ are different, which results in the differing results. Assuming that a "b c" d e was entered on the command line, then "$@" results in this expansion on the for loop (quoting from the command line is preserved):

 for  x in  a "b c" d e

while "$*" results in:

 for x in "a b c d e"

Here the command line arguments are converted to a single token and thus the loop executes only once with "a b c d" assigned to x.

For the last example, $* (no quotes) evaluates to just a b c d on the loop statement (quoting from the command line is not preserved) and thus the loop is executed one time for each and thus each is presented on a separate line.

Hope this makes it more clear.

Yeah, that makes sense. Thanks so much.