One of the basic things required in Bash is detecting the number of arguments passed to a script.
The reason behind that is being able to modify the behaviour of your script depending on the value and on the number of arguments passed to it.
How do you find the number of arguments in Bash?
Bash provides the built-in variable $# that contains the number of arguments passed to a script. A common way of using $# is by checking its value at the beginning of a Bash script to make sure the user has passed the correct number of arguments to it.
In this article I will show you how to use the $# variable to see the number of arguments passed to a script. We will also verify that the number of arguments passed is correct.
This is a technique used to stop the execution of your script immediately if the number of arguments provided to the script is incorrect. It allows to avoid error later on during the execution of the script.
Let’s start!
Print the number of arguments passed to a Bash Script
We will create a very simple Bash script that prints that number of arguments passed to it in the terminal.
Here is the code of the script, called arguments.sh
#!/bin/bash
echo $#
Set the executable permissions for the script to be able to run it via the terminal. To do that use the chmod command:
chmod +x arguments.sh
This is the output of the script when I pass a different number of arguments to it:
$ ./arguments.sh
0
$ ./arguments.sh test1
1
$ ./arguments.sh test1 test2
2
As you can see the value of the built-in variable $# contains the number of arguments I pass from the terminal when I run the script.
Let’s take it a step further!
Verify That The Number of Arguments Is Correct
I have decided to create a script that calculates the sum of two numbers and the first thing I want to make sure is that the user passes only two arguments to it.
What could happen if the user passes only one number and I try to calculate the sum anyway?
Let’s see…
In the first version of my script I simply calculate the sum of the two numbers without any additional check of the arguments:
#!/bin/bash
num1=$1
num2=$2
sum=$(($1+$2))
echo $sum
$1, $2 … $N are built-in Bash variables used to indicate the value of the first, the second and the nth argument passed to a Bash script.
Here is the output if I pass two arguments to it:
$ ./sum.sh 1 2
3
The script works well, so do I really need to add anything else to it?
Let’s see what happens if I don’t provide any arguments to my script:
$ ./sum.sh
./sum.sh: line 5: +: syntax error: operand expected (error token is "+")
The script raises a syntax error because it expects an operand. After all we want to calculate the sum of two numbers.
And what happens if I pass one argument?
$ ./sum.sh 1
./sum.sh: line 5: 1+: syntax error: operand expected (error token is "+")
Exactly the same error.
How can we avoid this?
We can enforce the number of arguments the script requires before we calculate the sum of the two numbers.
To do that we can use and if statement that verifies the value of the $# variable.
Once again…
The $# variable contains the number of arguments passed to a Bash script.
We will update our script to first verify that the number of arguments the user passes is two:
#!/bin/bash
if [ $# -ne 2 ]; then
echo The number of arguments provided is incorrect. Please provide two numbers.
exit 1
fi
num1=$1
num2=$2
sum=$(($1+$2))
echo $sum
This time if I execute the script passing no arguments, one argument or more than two arguments the script prints the error message I have chosen and stops its execution.
In the last execution you can see that, as expected, the script works well with two arguments:
$ ./sum.sh
The number of arguments provided is incorrect. Please provide two numbers.
$ ./sum.sh 1
The number of arguments provided is incorrect. Please provide two numbers.
$ ./sum.sh 1 2 3
The number of arguments provided is incorrect. Please provide two numbers.
$ ./sum.sh 1 2
3
Can you see how I stop the execution of the script after printing the error message?
I use the exit command passing to it the number 1 as argument to indicate that the script has failed.
In Bash the exit code 0 represents a success, while exit codes different than 0 represent failure.
Improving the Error Message Based on the Number of Arguments
Now, to provide a better user experience I was to customise the error message based on the number of arguments.
The error message will be different if the user passes no arguments, one argument or more than two arguments to the Bash script.
This time instead of using a simple if statement I will use an if elif statement considering that I want to verify three different conditions:
#!/bin/bash
if [ $# -eq 0 ]; then
echo You have provided zero arguments. Two are required.
exit 1
elif [ $# -eq 1 ]; then
echo You have provided one argument. Two are required.
exit 2
elif [ $# -gt 2 ]; then
echo You have provided more than two arguments. Two are required.
exit 3
fi
num1=$1
num2=$2
sum=$(($1+$2))
echo $sum
In the first version of our script we were only verifying if the number of arguments was not two and to do that we were using the -ne numeric comparison operator that stands for “not equal”.
This time we use the following operators:
- -eq operator (equal): checks if the value of $# is equal to a specific value.
- -gt operator (greater than): checks if the value of $# is bigger than the value specified, in this case two.
This is just an example to show you how you can validate the arguments of your scripts.
Find the Number of Arguments Passed to a Bash Function
We have seen how to verify the number of arguments passed to a Bash script.
Another scenario in which we pass arguments in Bash is when we call a function.
Let’s see how to find out the number of arguments passed to a Bash function!
I will refactor our script to create a function called calculate_sum() instead of calculating the sum in the “main” of the script.
The function takes two arguments, calculates their sum and returns the result:
#!/bin/bash
calculate_sum() {
sum=$(($1+$2))
return $sum
}
if [ $# -ne 2 ]; then
echo The number of arguments provided is incorrect. Please provide two numbers.
exit 1
fi
num1=$1
num2=$2
calculate_sum num1 num2
echo $?
Here is the way this script works:
- Define the calculate_sum() function at the beginning of the script.
- Call the function passing to it the variables num1 and num2.
- Print the return value of the function using the $? variable.
If I want to see the number of arguments passed to the function, I can use exactly the same variable we have used to print the number of arguments passed to the script: $#.
Update the function to print the value of $# so we can confirm the value is correct (we are passing two arguments to the function):
calculate_sum() {
echo The number of arguments passed to the function is: $#
sum=$(($1+$2))
return $sum
}
And if I run the script I can see that the function receives two arguments when it’s called:
$ ./sum.sh 1 2
The number of arguments passed to the function is: 2
3
Makes sense?
Conclusion
In this tutorial we have learned how to get the number of arguments passed to a Bash script. We have also seen how to use this information to make our script more robust.
The validation we have implemented at the beginning of the script allows to execute the full script only when the script receives the correct number of arguments.
In our case the script was very simple and the error that was occurring without validation was easy to spot.
But if the length of your script grows it can become a lot harder to spot errors caused by an incorrect number of arguments passed by the user.
That’s why it’s so important verifying the number of arguments as first thing in all your scripts.
Finally we have seen that the $# variable can be used in Bash to know the number of arguments passed to a script and also to a function.
Related FREE Course: Decipher Bash Scripting
Claudio Sabato is an IT expert with over 15 years of professional experience in Python programming, Linux Systems Administration, Bash programming, and IT Systems Design. He is a professional certified by the Linux Professional Institute.
With a Master’s degree in Computer Science, he has a strong foundation in Software Engineering and a passion for robotics with Raspberry Pi.