1. Introduction

We’ve previously looked at how to pass command-line arguments to a bash script. In this tutorial, we’ll take a look at how we can use these arguments inside the bash script.

Further reading:

How to Pass Command Line Arguments to Bash Script

Explore different ways of passing command-line arguments to the bash script during run time

How to Use the cd Command in Bash Scripts

Learn how to use the cd command in Linux Bash Scripts.

Reading Output of a Command Into an Array in Bash

Learn a few ways to save multi-line output into a Bash array

2. Processing the Input

Let’s take a look at the different ways in which the arguments passed to a bash script can be processed inside the script

2.1. Positional Parameters

Arguments passed to a script are processed in the same order in which they’re sent. The indexing of the arguments starts at one, and the first argument can be accessed inside the script using $1. Similarly, the second argument can be accessed using $2, and so on. The positional parameter refers to this representation of the arguments using their position.

Let’s take an example of the following script, userReg-positional-parameter.sh, which prints username, age, and full name, in that order:

echo "Username: $1";
echo "Age: $2";
echo "Full Name: $3";

Now, let’s run this script with the three input parameters:

sh userReg-positional-parameter.sh john 25 'John Smith'

The output will be:

Username : john
Age: 25
Full Name: John Smith

2.2. Flags

Using flags is a common way of passing input to a script. When passing input to the script, there’s a flag (usually a single letter) starting with a hyphen (-) before each argument.

Let’s take a look at the userReg-flags.sh script, which takes three arguments: username (-u), age (-a), and full name (-f).

We’ll modify the earlier script to use flags instead of relying on positional parameters. The getopts function reads the flags in the input, and OPTARG refers to the corresponding values:

while getopts u:a:f: flag
do
    case "${flag}" in
        u) username=${OPTARG};;
        a) age=${OPTARG};;
        f) fullname=${OPTARG};;
    esac
done
echo "Username: $username";
echo "Age: $age";
echo "Full Name: $fullname";

Let’s run this script with the same input as before, only this time, we’ll add flags to the input:

sh userReg-flags.sh -f 'John Smith' -a 25 -u john

The output is the same as before, though we have shifted the positions of the username and full name arguments:

Username : john
Age: 25
Full Name: John Smith

Here, we’re using the getopts function to parse the flags provided as input and the case block to assign the value specified to the corresponding variable.

2.3. Loop Construct

Positional parameters, while convenient in many cases, can’t be used when the input size is unknown. The use of a loop construct comes in handy in these situations.

The variable [email protected] is the array of all the input parameters. Using this variable within a for loop, we can iterate over the input and process all the arguments passed.

Let’s take an example of the script users-loop.sh, which prints all the usernames that have been passed as input:

i=1;
for user in "[email protected]" 
do
    echo "Username - $i: $user";
    i=$((i + 1));
done

Now, let’s run the script:

sh users-loop.sh john matt bill 'joe wicks' carol

And we’ll see our output:

Username - 1: john
Username - 2: matt
Username - 3: bill
Username - 4: joe wicks
Username - 5: carol

In the above example, we’re iterating the user variable over the entire array of input parameters. This iteration starts at the first input argument, john, and runs until the last argument, carol, though the size of the input is unknown.

2.4. Shift Operator

Shift operator in bash (syntactically shift n, where n is the number of positions to move) shifts the position of the command line arguments. The default value for n is one if not specified.

The shift operator causes the indexing of the input to start from the shifted position. In other words, when this operator is used on an array input, the positional parameter $1 changes to the argument reached by shifting n positions to the right from the current argument bound to positional parameter $1.

Consider an example script that determines whether the input is odd or even:

sh parityCheck.sh 13 18 27 35 44 52 61 79 93

From the above discussion on the positional parameter, we now know that $1  refers to the first argument, which is 13. Using the shift operator with input 1 (shift 1) causes the indexing to start from the second argument. That is, $1 now refers to the second argument (18). Similarly, calling shift 2 will then cause the indexing to start from the fourth argument (35).

Let’s again take a look at the example of users script discussed above. Instead of using the [email protected] variable and iterating over it, we’ll now use the shift operator. The $# variable returns the input size:

i=1;
j=$#;
while [ $i -le $j ] 
do
    echo "Username - $i: $1";
    i=$((i + 1));
    shift 1;
done

Let’s run the script with the same input as above:

sh users-shift-operator.sh john matt bill 'joe wicks' carol

The output will be the same as before:

Username - 1: john
Username - 2: matt
Username - 3: bill
Username - 4: joe wicks
Username - 5: carol

In this example, we’re shifting the positional parameter in each iteration by one until we reach the end of the input. Therefore, $1 refers to the next element in the input each time.

3. Conclusion

In this tutorial, we looked at how arguments passed to a bash script during runtime can be processed inside the script in different ways:

  • Positional parameters can be used when the input size is fixed and the order of the arguments in the input is known
  • With flags, the order of the arguments in the input doesn’t matter
  • Loop construct comes in handy when the input size is unknown
  • Shift operator causes indexing to start from the argument at the shifted position
  • The variable [email protected] returns the array of input parameters, and $# returns the size of the input array

As always, examples used in this article are available over on GitHub.

Subscribe
Notify of
guest
5 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Tim
Tim
3 months ago

for

user

in

"[email protected]" do
...
 
should be
 
for

user

in

"[email protected]"
do

Loredana Crusoveanu
Loredana Crusoveanu
2 months ago
Reply to  Tim

Hi Tim,
Thanks for catching that. We’ll update the article.

Abid Esmail
Abid Esmail
2 months ago

I tried this on a mac and I needed to add a semicolon after flag variable in the while statement. Here’s my script:
 while getopts “:d:b” flag; do
     case “${flag}” in
         d ) disk=${OPTARG};;
         * ) echo “Usage: $0 [-d]”;;
     esac
 done

 echo “disk=: ${disk}”;

Loredana Crusoveanu
Loredana Crusoveanu
1 month ago
Reply to  Abid Esmail

Hi Abid,

We’ve updated the article to put the “do” on the next line, so it should work ok now.

Thanks.

Meir Gabay
1 month ago

I created a script, bargs – https://github.com/unfor19/bargs, which helps in wrapping your Bash script with command line arguments. I hope you’ll find it useful