The difference between += and =+

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.


Note also that "$@" is magic only when there's nothing else in the quotes. These are identical:

set -- a "b c" d
some_func "foo $*"  
some_func "foo $@"

In both cases, some_func receives one argument.


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