They are all related to "all the arguments to the shell", but behave differently. The following script demonstrates each one of $*, $@, "$@" and "$*" in turn by echoing out the arguments passed in:
#! /bin/bash
echo +--- Using "\$*"
cnt=1
for i in $*
do
  echo arg$cnt: $i
  cnt=$(($cnt+1))
done
echo +--- Using \"\$*\"
cnt=1
for i in "$*"
do
  echo arg$cnt: $i
  cnt=$(($cnt+1))
done
echo +--- Using "\$@"
cnt=1
for i in $@
do
  echo arg$cnt: $i
  cnt=$(($cnt+1))
done
echo +--- Using \"\$@\"
cnt=1
for i in "$@"
do
  echo arg$cnt: $i
  cnt=$(($cnt+1))
done
Running the script, produces the following output:
sharfah@starship:~> echoArgs.sh  mars "kit kat" twix
+--- Using $*
arg1: mars
arg2: kit
arg3: kat
arg4: twix
+--- Using "$*"
arg1: mars kit kat twix
+--- Using $@
arg1: mars
arg2: kit
arg3: kat
arg4: twix
+--- Using "$@"
arg1: mars
arg2: kit kat
arg3: twix
When unquoted, $* and $@ do the same thing. They treat each "word" (sequence of non-whitespace characters) as a separate argument. This leads to the single argument "kit kat" being broken into two which may not be desired. When quoted, $* and $@ behave differently. "$*" treats the entire argument list as a single argument, but "$@" treats the arguments just as they were when passed in.
So, which should you use? In almost all cases you would use "$@" in order to preserve arguments with spaces (or quoted arguments) when being passed in on the command line or from one script to another. Never use the unquoted $* or $@ unless you are absolutely sure that you won't need to deal with arguments with spaces in them. If you need to combine all arguments into one, use "$*".
 
No comments:
Post a Comment
Note: Only a member of this blog may post a comment.