What is the Difference Between $@ and $* in Bash?

In Bash, the $@ and $* are both special parameters that refer to all of the positional parameters passed to a script or function. The $@ represents all the positional parameters as separate words while the $* is similar to $@, but it represents all the positional parameters as a single word. 

This article will illustrate the difference between $@ and $*, special parameters in Bash:

  • In Terms of Quoting 
  • In Terms of Looping
  • In Terms of Special Characters

Difference Between $@ and $* in Bash in Terms of Quoting

When users reference “$@” within double quotes, each positional parameter is quoted separately. It represents that the whitespace within each parameter is preserved. 

Example 1: Using “$@” Within Double Quotes

An example is considered to reference “$@” within double quotes in the “script.sh” file. The script is provided below:

#!/bin/bash

echo "Arguments: $@"

Save and exit the file.

Execute the Script File

To call the above-mentioned script, first get permission by executing the “sudo chmod +x /script.sh” command. 

After that, pass two arguments “hello world” and “foo bar” to the “script.sh”:

$ ./script.sh "hello world" "foo bar"

The output shows that the two arguments containing spaces are quoted separately, so the spaces are preserved in the output.

Example 2: Using “$*” Within Double Quotes

On the other hand, when users reference “$*” within double quotes. All parameters are combined into a single string, separated by the first character of the variable (usually a space). For example, consider the following script:

#!/bin/bash

echo "Arguments: $*"

Save and exit the script file.

Execute the Script File

Pass two arguments “hello world” and “foo bar” to the “script.sh”:

$ ./script.sh "hello world" "foo bar"

The output shows that the two arguments containing spaces are concatenated into a single string, with no indication that there were originally two separate arguments.

Difference Between $@ and $* in Bash in Terms of Looping

When users loop over $@ or $*, the behavior is different. Using $@, each positional parameter is treated as a separate word, so the loop variable contains the value of each parameter separately. 

Example 1: Using “$@” in for Loop 

An example is considered using “$@” in the for loop and display argument via the “arg” variable:

#!/bin/bash

for arg in "$@"
do
    echo "Argument: $arg"
done

Save and Exit the script.

Execute the Script

After saving the script file, call the “script.sh” file by passing “foo bar baz” arguments:

$ ./script.sh foo bar baz

The output shows that each word is enlisted in a separate line.

Example 2: Using “$*” in for Loop

On the other hand, when users loop over $*, the entire list of positional parameters are treated as a single word, so the loop variable contains the entire list of parameters. The script is provided below:

#!/bin/bash

for arg in "$*"
do
    echo "Argument: $arg"
done

Save and exit the file.

Execute the Script

To call the “script.sh” file, pass arguments “foo bar baz” in the following command:

$ ./script.sh foo bar baz

The output shows that the entire list of parameters is treated as a single word, and there is no way to distinguish between the individual parameters.

Difference Between $@ and $* in Bash in Terms of Special Characters

To handle special characters like quotes and backslashes, users reference $@ within double quotes. Each positional parameter is quoted separately, so any special characters within the parameters are preserved. 

On the other hand, when users reference $* within double quotes, all positional parameters are concatenated into a single string, so any special characters within the parameters may be interpreted differently in the following script:

#!/bin/bash

echo "Arguments: $@"
echo "Arguments: $*"

Save and exit the script.sh file.

Execute the Script

To execute the script file, users can pass arguments such as “hello \“world\”” ‘foo$bar’ to the “script.sh” file in the terminal:

$ ./script.sh "hello \"world\"" 'foo$bar'

The output returns the same output in two lines, but the first line contains the separate words and the second line concatenates into a single string.

Conclusion

In Bash, the main difference between $@ and $* is that “$@” preserves the individual arguments as separate words, while other preserves them as a single string. The distinction between these two can be important in certain situations, especially when it comes to handling whitespace and special characters in the arguments.

This article has explained the main difference between $@ and $* along with examples including quotes, loop, and special characters in bash.