Command Line Arguments in Shell/Bash Scripts [Tutorial]

Command Line Arguments in Bash Scripts

This tutorial explains how to pass command-line arguments to your bash scripts. There are many examples included to help get you started.

Bash/Shell scripts are a great way to automate your Linux workflow and speed up your workday so you can leave the office early (or hide in the server room until 5 pm hits).

Making scripts re-usable makes them more useful – you don’t need to write a script that does the same task for different sets of information or on different days – you can re-use the same script and provide different parameters – instructions provided to the script via the command line. This is sometimes also known as using command line arguments.

For example, you may have a script that outputs some text to a file. If you wanted to change the file name, you’d have to edit the script. If you wanted the script to output to multiple files, you might need multiple copies of the script on hand. Using parameters, you could have a single script that can output to any number of files, with any name, passed as parameters from the command line.

There are a few different ways to pass these parameters – options and their values – to your script, depending on what you’re trying to achieve. Here are a few methods, with examples:

The getopts / Flags Method of Reading Command Line Input

  • getopts is a shell command which retrieves options (or flags) from the command line input and makes their value (or argument) available for use in your scripts
    • Options are a single letter preceded by a – (dash), followed by the value to pass, like -v value
  • Best used when the order doesn’t matter
  • Probably the best of all of the methods listed here

getopts Bash script Example

This example script takes three options for a fast-food order:

  • -o for order
  • -s for size
  • -d for drink

fastFoodOrder.sh

#!/bin/bash

# Use a while loop to parse through the options o, s, d
while getopts o:s:d: flag
do

    # Match each option (which has been assigned to the $flag variable) to it's meaning using a case statement block
    # OPTARG will be the value received from getopts for the corresponding option and is assigned to a variable depending on the flag
    case "${flag}" in
        o) order=${OPTARG};;
        s) size=${OPTARG};;
        d) drink=${OPTARG};;
    esac

done

# The values as passed to the options are now available in their corresponding variable
echo "Order: $order";
echo "Size: $size";
echo "Drink: $drink";

Click here to find out more about the #!/bin/bash line at the beginning of bash scripts.

To run this, enter the following:

bash ./fastFoodOrder.sh -d Cola -o 'Fish Burger Meal' -s Large

Which will result in the script outputting:

Order: Fish Burger Meal
Size: Large
Drink: Cola

As you can see in the above output – the order the options were supplied in didn’t matter.

Why is ./ used when executing scripts?

Passing Multiple Values to the Same Option

It is also possible to pass an option multiple times for multiple values – they will then be available in the script as an array.

This is the best way of passing multiple values to a single option as it allows for any character to be used in the value – passing the values in quotes or using a delimiter will limit this.

fastFoodOrderExtras.sh

#!/bin/bash

# Use a while loop to parse through the options o, s, d, e
while getopts o:s:d:e: flag
do

    # Match each option (which has been assigned to the $flag variable) to it's meaning using a case statement block
    # OPTARG will be the value received from getopts for the corresponding option and is assigned to a variable depending on the flag
    case "${flag}" in
        o) order=${OPTARG};;
        s) size=${OPTARG};;
        d) drink=${OPTARG};;
        e) extras+=${OPTARG};;# Create or append an array variable to hold the multiple extras values passed
    esac

done

# The values as passed to the options are now available in their corresponding variable
echo "Order: $order";
echo "Size: $size";
echo "Drink: $drink";
echo "The list of extras is '${extras[@]}'"

# Loop through the multiple extras values
for val in "${extras[@]}"; do
    echo $val
done

The above script accepts multiple -e options for adding extras, as seen below:

bash ./fastFoodOrderExtras.sh -d Cola -o 'Fish Burger Meal' -s Large  -e Sauce -e Salt -e Pepper

The script will output:

Order: Fish Burger Meal
Size: Large
Drink: Cola
The list of extras is 'SauceSaltPepper'
SauceSaltPepper

Using Positional Parameters in Scripts

  • Used when there will be a known number of arguments/parameters in a specific order
  • Best used for simpler scripts

Example

fastFoodOrder.sh

#!/bin/bash

echo "Order: $1";
echo "Size: $2";
echo "Drink: $3";

To run this, enter the following:

bash ./fastFoodOrder.sh 'Fish Burger Meal' Large Cola

Which will result in the script outputting:

Order: Fish Burger Meal
Size: Large
Drink: Cola

Note that if the options were provided out of order, the values would all be mixed up. Position matters using this method!

bash ./fastFoodOrder.sh 'Fish Burger Meal' Cola Large

Would result in the values being assigned incorrectly:

Order: Fish Burger Meal
Size: Cola
Drink: Large

Using Loops to Read Command Line Parameters

  • Best used when the number of options/arguments isn’t known in advance
    • For example, you might be supplying a list of ingredients for a recipe
  • It uses the built-in variable [email protected], which contains an array of all of the input options supplied by the user

Example

recipe.sh

#!/bin/bash

i=1; # This value is the iterator value - the current number of loops that have completed

for ingredient in "[email protected]" # loop through [email protected] which is an array of all passed input parameters
do
    echo "Ingredient number $i is $ingredient";# Print the $ingredient which was passed to the script when it was called
    i=$((i + 1)); # Increment the iterator value so we know how many times we have looped
done

Run it:

sh ./recipe.sh bread lettuce cheese hamburger

Which will output:

Ingredient number 1 is bread
Ingredient number 2 is lettuce
Ingredient number 3 is cheese
Ingredient number 4 is hamburger
SHARE:
nv-author-image

Brad Morton

I'm Brad, and I'm nearing 20 years of experience with Linux. I've worked in just about every IT role there is before taking the leap into software development. Currently, I'm building desktop and web-based solutions with NodeJS and PHP hosted on Linux infrastructure. Visit my blog or find me on Twitter to see what I'm up to.

Leave a Reply

Your email address will not be published. Required fields are marked *