Bash Scripting – using special variables related to parameters
A few special bash shell variables track command line parameters. This section describes what they are and how to use them.
Counting parameters
As you saw in the last learning article, you should verify command line parameters before using them in your script. For scripts that use multiple command line parameters, this checking can get tedious.
Instead of testing each parameter, you can count how many parameters were entered on the command line. The bash shell provides a special variable for this purpose.
The special $# variable contains the number of command line parameters included when the script was run. You can use this special variable anywhere in the script, just like a normal variable:
$ cat test8.sh
#!/bin/bash
# getting the number of parameters
#
echo There were $# parameters supplied.
$
$ ./test8.sh
There were 0 parameters supplied.
$
$ ./test8.sh 1 2 3 4 5
There were 5 parameters supplied.
$
$ ./test8.sh 1 2 3 4 5 6 7 8 9 10
There were 10 parameters supplied.
$
$ ./test8.sh “Rich Blum”
There were 1 parameters supplied.
$
Now you have the ability to test the number of parameters present before trying to use them:
$ cat test9.sh
#!/bin/bash
# Testing parameters
#
if [ $# -ne 2 ]
then
echo
echo Usage: test9.sh a b
echo
else
total=$[ $1 + $2 ]
echo
echo The total is $total
echo
fi
#
$
$ bash test9.sh
Usage: test9.sh a b
$ bash test9.sh 10
Usage: test9.sh a b
$ bash test9.sh 10 15
The total is 25
$
The if-then statement uses the -ne evaluation to perform a numeric test of the command line parameters supplied. If the correct number of parameters isn’t present, an error message displays showing the correct usage of the script.
This variable also provides a cool way of grabbing the last parameter on the command line without having to know how many parameters were used. However, you need to use a little trick to get there.
If you think this through, you might think that because the $# variable contains the value of the number of parameters, using the variable${$#} would represent the last command line parameter variable. Try that and see what happens:
$ cat badtest1.sh
#!/bin/bash
# testing grabbing last parameter
#
echo The last parameter was ${$#}
$
$ ./badtest1.sh 10
The last parameter was 15354
$
Wow, what happened? Obviously, something went wrong. It turns out that you can’t use the dollar sign within the braces. Instead, you must replace the dollar sign with an exclamation mark. Odd, but it works:
$ cat test10.sh
#!/bin/bash
# Grabbing the last parameter
#
params=$#
echo
echo The last parameter is $params
echo The last parameter is ${!#}
echo
#
$
$ bash test10.sh 1 2 3 4 5
The last parameter is 5
The last parameter is 5
$
$ bash test10.sh
The last parameter is 0
The last parameter is test10.sh
$
Perfect. This script also assigned the $# variable value to the variable params and then used that variable within the special command line parameter variable format as well. Both versions worked. It’s also important to notice that, when there weren’t any parameters on the command line, the $# value was zero, which is what appears in the params variable, but the ${!#} variable returns the script name used on the command line.
Grabbing all the data
In some situations you want to grab all the parameters provided on the command line. Instead of having to mess with using the $# variable to determine how many parameters are on the command line and having to loop through all of them, you can use a couple of other special variables.
The $* and $@ variables provide easy access to all your parameters. Both of these variables include all the command line parameters within a single variable.
The $* variable takes all the parameters supplied on the command line as a single word. The word contains each of the values as they appear on the command line. Basically, instead of treating the parameters as multiple objects, the $* variable treats them all as one parameter.
The $@ variable, on the other hand, takes all the parameters supplied on the command line as separate words in the same string. It allows you to iterate through the values, separating out each parameter supplied. This is most often accomplished using the for command.
It can easily get confusing to figure out how these two variables operate. Let’s look at the difference between the two:
$ cat test11.sh
#!/bin/bash
# testing $* and $@
#
echo
echo “Using the \$* method: $*”
echo
echo “Using the \$@ method: $@”
$
$ ./test11.sh rich barbara katie jessica
Using the $* method: rich barbara katie jessica
Using the $@ method: rich barbara katie jessica
$
Notice that on the surface, both variables produce the same output, showing all the command line parameters provided at once.
The following example demonstrates where the differences are:
$ cat test12.sh
#!/bin/bash
# testing $* and $@
#
echo
count=1
#
for param in “$*”
do
echo “\$* Parameter #$count = $param”
count=$[ $count + 1 ]
done
#
echo
count=1
#
for param in “$@”
do
echo “\$@ Parameter #$count = $param”
count=$[ $count + 1 ]
done
$
$ ./test12.sh rich barbara katie jessica
$* Parameter #1 = rich barbara katie jessica
$@ Parameter #1 = rich
$@ Parameter #2 = barbara
$@ Parameter #3 = katie
$@ Parameter #4 = jessica
$
Now we’re getting somewhere. By using the for command to iterate through the special variables, you can see how they each treat the command line parameters differently. The $* variable treated all the parameters as a single parameter, while the $@ variable treated each parameter separately. This is a great way to iterate through command line parameters.
Thanks for such a useful quick and crisp info….however I would like to add one suggestion like why don’t you add tasks to apply the same tutorials.
so that we can practise and test our understanding in a better way…:)
Thanks Arun, for the suggestion.We will make our future articles task oriented.
Hi Ramdev,
Thanks for response…
Kindly add tasks in your daily mails in bash scripting mails…
If I don’t have permission to view the script and see how many parameters needs to be passed to a certain script or program, how to know how parameters we have to passed to a script or a program.