We would have often come across Bash scripts that expect arguments either in the form of user input or in conjunction with those scripts. When developing such scripts, it becomes of paramount importance to validate and sanitize the input arguments. This prevents the script from behaving in an unexpected manner.
This guide will cover different ways of checking the existence of input arguments in a Bash script.
Here’s a quick overview of the Bash tools we are going to use:
- $# to fetch the number of arguments supplied to a script.
- Unary test operators (-n and -z) on positional parameter.
- Shift command to left shift the command line arguments.
Using the special variable $#
Bash comes with some special variables including $# to store the number of input arguments passed to the script. If the script expects at least one input argument, we can check if the "$#" variable is greater than zero.
Let us consider an example script named argCheck1.sh with execute permissions.
#!/bin/bash
if [ "$#" -eq 0 ]
then
echo "{ERROR} The script expects at least one input. Exiting"
exit 1
fi
echo "Total number of input arguments provided are: $#"
The "-eq” operator is testing if the "$#" variable is numerically equal to 0.
An error message will appear on the screen and the script will exit with a status code of 1 when the condition becomes true. Otherwise, the script will echo the count of arguments.
When we run the script:
./argCheck1.sh
There is no argument supplied with the script. The error message will be displayed and exit with status code 1 will take place.
Run with arguments:
./argCheck1.sh London Paris Tokyo Dubai Moscow
Since we have passed arguments to the script, we get to see the correct count being returned as 5.
Using the test on positional parameter
As there has been a mention of special variables, another one that can be used to check an argument in Bash is the positional variable. $1 is the positional parameter storing the very first argument supplied to the script.
We have also previously seen the use of the '-n' and '-z' options available with Bash. These are unary operators to check the length of a string variable.
-n option
We use this operator to examine if the length of the variable is non-zero. True is returned if the string is non-empty. Using this tool, we can check if the input argument exists or not.
#!/bin/bash
if [ -n "$1" ]
then
echo "Input argument present"
else
echo "{ERROR} Input argument not present"
exit 1
fi
The "-n" option acts on the first argument to determine if the first input argument is not empty. If non-empty, the script displays a success message. Otherwise, the script outputs an error message and terminates the script with a status code of 1.
When we run the script:
./argCheck2.sh
As there is no argument supplied with the script, it will simply echo the error message and exit with status code 1.
Run with arguments:
./argCheck2.sh London
Since we have passed arguments to the script, the if condition gets satisfied and we get the prompt that the input argument is present.
-z option
This operator examines if the length of the variable is zero by returning true if the string is empty. We can integrate this in our script to test the presence of the input argument.
#!/bin/bash
if [ -z "$1" ]
then
echo "{ERROR} Input argument not present"
exit 1
else
echo "Input argument present"
fi
The "-z" option acts on the first argument to verify if it is empty. The script will display a success message if it is not empty. An error message will appear and the script will terminate with a status code of 1 otherwise.
When we run the script:
./argCheck3.sh
As there is no argument supplied with the script, the "if" condition gets satisfied. It will simply echo the error message and exit with status code 1.
Run with arguments:
./argCheck3.sh London
Since we have passed arguments to the script, we get the prompt that the input argument is present.
Using the shift command
The built-in shift command moves the command line arguments one position to the left. This way, the first argument is lost after using shift command. We are going to use this fundamental principle in an example to understand how the shift command checks the number of passed arguments to the script.
#!/bin/bash
c=0
while [ $# -gt 0 ]; do
shift
((c++))
done
echo "Total number of input arguments provided are: $c"
The count variable 'c' holds the specified argument’s counter. The while loop checks if the number of arguments the script received ($#) is greater than 0. In each run, the shift command jumps the positional parameter to the left by one.
For each shift we increment the value of c by one. After the loop is finished, we display the total number of arguments.
Different scenarios/ Examples
There could be different situations where we have to validate the input arguments. We will learn how to handle the legitimate arguments and discard the rest.
If no arguments are supplied
We can forget to pass arguments to a script that expects it. We should terminate the script with an error message. We can create a small script snippet to handle this situation.
#!/bin/bash
if [ "$#" -eq 0 ]
then
echo "{ERROR} The script expects at least one input. Exiting"
exit 1
fi
As seen previously, we have used to the special variable "$#" to get the count of the input parameters. When no input is passed, this count is zero. Hence, we can simply log an error message and exit the script completely.
If one or more arguments are supplied
Sometimes, the script looks for at least one argument. Let us understand this example to check for at least one argument, otherwise we exit the script:
#!/bin/bash
if [ "$#" -lt 1 ]
then
echo "{ERROR} The script expects at least one input. Exiting"
exit 1
fi
The special variable "$#" is used again to get the count of the input parameters. When no input is passed, this count is zero. We use -lt to check if the left operand is less than that of the right operand. We terminate the script by echoing the error with an exit status of 1.
If the arguments are supplied, this count will not be less than one. The code flow will never reach the if block and continue as normal without terminating.
If a specific argument is supplied
We can check if a specific argument is passed to the script by getting the length of the argument. We will check the existence of the 3rd argument in this example.
#!/bin/bash
if [ -z "$3" ]
then
echo "{ERROR} 3rd Input argument not present"
exit 1
else
echo "3rd input argument is $3"
fi
The third argument passed to the script will always be available in the special variable $3. Using the unary operator -z, we determine if the length of $3 is zero by returning true if empty.
If not, the script will display a success message, displaying the third argument. Otherwise, the script will throw an error message and exit out. We can also use the -n operator on $3 as seen previously.
If the supplied arguments count is as expected
There could be situations where the script is looking for "x" number of arguments, but receives only "y". We should handle this gracefully by counting the number of arguments. Let us see how we can achieve this.
#!/bin/bash
if [ "$#" -ne 4 ]
then
echo "{ERROR} Script expects 4 arguments. Supplied is $#"
exit 1
fi
The special variable "$#"fetches the count of the input parameters. We do a numeric comparison using the -ne to check if the left operand is not equal to the right operand. If not equal, we terminate the script by echoing the error with an exit status of 1.
When we pass fewer or greater than 4 arguments, the if condition is fulfilled. This will print the error statement and exit without any further execution.
If argument is a string
There could be numerous places, where we want the input to be strictly of string data type. We need this check when validating certain fields like name or city where we can only expect non-numeric characters. We can use regular expressions for this.
#!/bin/bash
if [ -z "$1" ]
then
echo "No input passed."
exit
elif [[ ! "$1" =~ ^[0-9]+$ ]]
then
echo "Input is of string type"
else
echo "Input is numeric"
fi
We first check if the input $1 is empty using the -z unary operator. If empty, we warn the user with an error message and exit the script to ensure no further processing gets carried out.
If the input is not empty, we reach the elif condition. The ~ operator instructs shell to match the value of $1 against the regular expression. The expression ^[0-9]+$ matches any string that consists only of one or more numeric digits. This combined with the ! operator does the exact opposite.
This means, if the input does not match the numeric pattern, it is safe to call it a string. We echo a message to show that the input is a string.
Finally, if it doesn’t match, we reach the else block as we are certain it is a number. We display the corresponding message.
Comments