bashcommand-line-arguments

Accessing bash command line args $@ vs $*


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?


Solution

  • 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