In many SO questions and bash tutorials I see that I can access command line args in bash scripts in two ways:
$ ~ >cat testargs.sh #!/bin/bash echo "you passed me" $* echo "you passed me" $@
Which results in:
$ ~> bash testargs.sh arg1 arg2 you passed me arg1 arg2 you passed me arg1 arg2
What is the difference between $*
and $@
?
When should one use the former and when shall one use the latter?
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.
"$@" Stores all the arguments that were entered on the command line, individually quoted ("$1" "$2" ...). 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.
bash [filename] runs the commands saved in a file. $@ 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.
The difference appears when the special parameters are quoted. Let me illustrate the differences:
$ set -- "arg 1" "arg 2" "arg 3" $ for word in $*; do echo "$word"; done arg 1 arg 2 arg 3 $ for word in $@; do echo "$word"; done arg 1 arg 2 arg 3 $ for word in "$*"; do echo "$word"; done arg 1 arg 2 arg 3 $ for word in "$@"; do echo "$word"; done arg 1 arg 2 arg 3
one further example on the importance of quoting: note there are 2 spaces between "arg" and the number, but if I fail to quote $word:
$ for word in "$@"; do echo $word; done arg 1 arg 2 arg 3
and in bash, "$@"
is the "default" list to iterate over:
$ for word; do echo "$word"; done arg 1 arg 2 arg 3
A nice handy overview table from the Bash Hackers Wiki:
Syntax | Effective result |
---|---|
$* | $1 $2 $3 … ${N} |
$@ | $1 $2 $3 … ${N} |
"$*" | "$1c$2c$3c…c${N}" |
"$@" | "$1" "$2" "$3" … "${N}" |
where c
in the third row is the first character of $IFS
, the Input Field Separator, a shell variable.
If the arguments are to be stored in a script variable and the arguments are expected to contain spaces, I wholeheartedly recommend employing a "$*"
trick with the input field separator set to tab IFS=$'\t'
.
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