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 $@, 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 "$@" # loop through $@ 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