Possible Duplicate:
What the difference between “$@” and “$*” in bash?
For years and on dozens of occasions, I have hesitated between the use of $*
and $@
in shell scripts. Having read the applicable section of Bash's manpage over and over again, having tried both $*
and $@
, I more or less completely fail to understand the practical difference of application between the two variables. Can you enlighten me, please?
I have been using $*
recently, but don't ask me why. I don't know why, because I don't know why $@
even exists, except as an almost exact synonym for $*
.
Is there any practical difference?
(I personally tend to use Bash, but remain agnostic regarding the choice of shell. My question is not specific to Bash as far as I know.)
There is no difference if you do not put $* or $@ in quotes. But if you put them inside quotes (which you should, as a general good practice), then $@ will pass your parameters as separate parameters, whereas $* will just pass all params as a single parameter.
This question already has answers here:The $@ holds list of all arguments passed to the script. The $* holds list of all arguments passed to the script.
So basically, $# is a number of arguments given when your script was executed. $* is a string containing all arguments. For example, $1 is the first argument and so on. This is useful, if you want to access a specific argument in your script.
$@ refers to all of a shell script's command-line arguments. $1 , $2 , etc., refer to the first command-line argument, the second command-line argument, etc. Place variables in quotes if the values might have spaces in them.
Unquoted, there is no difference -- they're expanded to all the arguments and they're split accordingly. The difference comes when quoting. "$@"
expands to properly quoted arguments and "$*"
makes all arguments into a single argument. Take this for example:
#!/bin/bash function print_args_at { printf "%s\n" "$@" } function print_args_star { printf "%s\n" "$*" } print_args_at "one" "two three" "four" print_args_star "one" "two three" "four"
Then:
$ ./printf.sh one two three four one two three four
Consider:
foo() { mv "$@"; } bar() { mv "$*"; } foo a b bar a b
The call to foo will attempt to mv file a to b. The call to bar will fail since it calls mv with only one argument.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With