1. Introduction
In Bash scripting, understanding the difference between $* and $@ is crucial for handling command-line arguments correctly. We use both variables to represent the command-line arguments passed to a script or function, but they can behave differently.
In this tutorial, we’ll explore the key distinctions between $* and $@ in Bash.
2. The $* Variable
The $* variable represents each command-line argument as a single string. The arguments are separated by spaces and aren’t joined together.
To illustrate the usage of this variable, let’s create a Bash script named dollarStar.sh:
#!/bin/bash
for arg in $*; do
echo "$arg"
done
Let’s explain it line by line:
- for arg in $*; do uses a for loop to iterate over the elements of $*
- echo “$arg” prints the value of the arg variable to the screen
- done marks the end of the loop body
We can use chmod +x dollarStar.sh to give the executive permission to dollarStar.sh. Let’s see what happens when we run it:
$ ./dollarStar.sh Journey to the cloud
Journey
to
the
cloud
In the example, Journey to the cloud are the command-line arguments. We see that $* splits them so that each argument becomes a separate string.
In general, we use $* when we want to treat every argument as a single string. This is suitable for string manipulation or passing them to another command.
2.1. Using “$*”
Enclosing the variable $* with double quotes means all arguments will be treated as a single string jointly.
If we replace $* with “$*” in dollarStar.sh and name the new script as dollarStarQuoted.sh:
for arg in "$*"; do
echo "$arg"
done
and give it the executive permission*,* we’ll get:
$ ./dollarStarQuoted.sh Journey to the cloud
Journey to the cloud
All the arguments are combined into a single word, with spaces between them.
3. The $@ Variable
The variable $@ treats each command-line argument as a separate element in an array.
As an example, let’s create another script (dollarAt.sh):
#!/bin/bash
for arg in $@; do
echo "$arg"
done
It iterates over the elements of $@. After setting the permissions, we can run it like our first script:
$ ./dollarAt.sh Journey to the cloud
Journey
to
the
cloud
We see that $@ preserves the original structure of the arguments and that we can access them as separate items within the loop.
We use $@ to preserve argument quoting or work with individual arguments within loops or functions.
3.1. Using “$@”
Both $@ and “*$@”* treat each command-line argument separately. If we change $@ to “$@” in dollarAt.sh and name the new script as dollarAtQuoted.sh:
for arg in "$@"; do
echo "$arg"
done
the result will be the same:
$ ./dollarAtQuoted.sh Journey to the cloud
Journey
to
the
cloud
In most cases, using $@ or “$@” instead of $* is safer and more flexible when working with command-line arguments because they preserve the original argument structure and make it easier to work with individual arguments in our bash script.
4. Comparison of $* and $@
If we pass quoted command-line arguments like “Journey to” “the cloud” to $* and $@, we get the same results as before:
$ ./dollarStar.sh "Journey to" "the cloud"
Journey
to
the
cloud
./dollarAt.sh "Journey to" "the cloud"
Journey
to
the
cloud
However, passing these quoted arguments to “$@” and “$*” gives different outputs. The quoted variable “$@” treats each quoted sequence of characters as an individual argument, but “$*” treats them as a single entity:
$ ./dollarStarQuoted.sh "Journey to" "the cloud"
Journey to the cloud
./dollarAtQuoted.sh "Journey to" "the cloud"
Journey to
the cloud
5. Conclusion
In this article, we explored the similarities and differences between $* and $@ and their quoted variants. They behave the same way when not quoted: They treat each argument as a separate entity and preserve spaces and special characters within individual arguments. However, their behavior is different if we quote them. While “$@” keeps individual arguments, “$*” treats them as a single entity.