Black Friday 2025 – NPI EA (cat = Baeldung on Linux)
announcement - icon

Yes, we're now running our Black Friday Sale. All Access and Pro are 33% off until 2nd December, 2025:

>> EXPLORE ACCESS NOW

Baeldung Pro – Linux – NPI EA (cat = Baeldung on Linux)
announcement - icon

Learn through the super-clean Baeldung Pro experience:

>> Membership and Baeldung Pro.

No ads, dark-mode and 6 months free of IntelliJ Idea Ultimate to start with.

Partner – Orkes – NPI EA (tag=Kubernetes)
announcement - icon

Modern software architecture is often broken. Slow delivery leads to missed opportunities, innovation is stalled due to architectural complexities, and engineering resources are exceedingly expensive.

Orkes is the leading workflow orchestration platform built to enable teams to transform the way they develop, connect, and deploy applications, microservices, AI agents, and more.

With Orkes Conductor managed through Orkes Cloud, developers can focus on building mission critical applications without worrying about infrastructure maintenance to meet goals and, simply put, taking new products live faster and reducing total cost of ownership.

Try a 14-Day Free Trial of Orkes Conductor today.

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.