Bash shell positional parameters and special variables

We frequently use arguments with the commands that we type on the command line interface. The options what we provide is called as Bash shell positional parameters.

Bash shell positional parameters and special variables

Example in the command $ls -l /tmp, ls is the command, l is the option & /tmp is the argument.

We can use some arguments with our bash shell scripts as well to influence the behavior of the code as per our requirements.
Positional parameters are arguments we type after the name of the script separated by spaces. They are $1, $2 & so on.
Just a note, in case you are using more than nine arguments with the script then the 10th & subsequent arguments need to be represented by ${10} & so on.
In case you write $10, the shell will interpret it as the value of $1 & append a zero to that value while printing.
I’ve modified the bargs.sh script used earlier to include the arguments $1 & $2.

In this article, we will demonstrate with examples, how we use positional parameters in shell scripts. We will also discuss some variables which have a special meaning to the shell like $0, $@ and $*.

$0

The first example in the article we look at is that of the special variable $0. This represents the name of the file/script which is being run.
To illustrate I wrote a small script bargs.sh with the following content

[root@sahil-centos ~]# cat bargs.sh
#!/bin/bash
echo "The name of the script is $0"

When I run the script, the name of the script gets substituted as the value of argument $0.

[root@sahil-centos ~]# bargs.sh
The name of the script is /root/bargs.sh
[root@sahil-centos ~]# ./bargs.sh
The name of the script is ./bargs.sh

Positional parameters

In the previous example, we used $0 within our script to represent the name of the script. In this example, we’ll show you how to use positional parameters like $1, $2 in a shell script.

#!/bin/bash
echo "The name of the script is $0"
echo "The first argument is $1"
echo "The second argument is $2"

I executed the script providing two arguments to it

[root@sahil-centos ~]# ./bargs.sh sahil suri
The name of the script is ./bargs.sh
The first argument is sahil
The second argument is suri

As you can notice from the above output, the argument sahil got substituted as the value for positional parameter $1 and the argument suri was substituted as the value of positional parameter $2.

$#

The variable $# represents the number of arguments typed with the script during execution. This is useful for applying a condition wherein you want a script to run only when the user enters a required number of arguments. I updated the bargs.sh script as follows

#!/bin/bash
echo "The name of the script is $0"
echo "The first argument is $1"
echo "The second argument is $2"
echo "you entered $# arguments"

The output from this script is as follows

[root@sahil-centos ~]# ./bargs.sh sahil suri
The name of the script is ./bargs.sh
The first argument is sahil
The second argument is suri
you entered 2 arguments

$* and $@

Both these arguments basically perform the same function, They hold the arguments that were entered with the shell script. But there is a subtle difference in the interpretation. I’ve expanded the script bargs.sh further to illustrate their usage.

#!/bin/bash
echo "The name of the script is $0"
echo "The first argument is $1"
echo "The second argument is $2"
echo "you entered $# arguments"
echo "The arguments entered are $*"
echo "The arguments entered are $@"

Output of the script is below

[root@sahil-centos ~]# ./bargs.sh sahil suri
The name of the script is ./bargs.sh
The first argument is sahil
The second argument is suri
you entered 2 arguments
The arguments entered are sahil suri
The arguments entered are sahil suri

The difference between $* & $@ isn’t apparent from the above example.
From what I’ve understood, the arguments $* and $@ will produce the same result unless we change the value of IFS (internal field separator) which is a white space by default.
$* counts each argument as an individual string whereas $@ interprets all the arguments as a single string.
With that understood, let’s see an example to demonstrate this.

I’ve updated our bargs.sh script mentioned below

#!/bin/bash

echo -e "\e[34m illustrating bash arguments \e[0m"

echo "the script name with path is:" $0
echo "the script name is:" `basename $0`
echo "the script location is:" `dirname $0`

echo "the 1st argument is:" $1
echo "the 2nd argument is:" $2

echo "the number of arguments are:" $#

echo "the arguments entered are" $*
echo "the arguments entered are" $@

echo "Changing field separator"
IFS='-'
echo "the arguments using $*" "$*"
echo "the arguments using $@" "$@"

The output from this script is as shown below

[root@sahil-centos ~]# ./bargs.sh sahil suri
illustrating bash arguments
the script name with path is: ./bargs.sh
the script name is: bargs.sh
the script location is: .
the 1st argument is: sahil
the 2nd argument is: suri
the number of arguments are: 2
the arguments entered are sahil suri
the arguments entered are sahil suri
Changing field separator
the arguments using $* sahil-suri
the arguments using $@ sahil suri

In the above example, I changed the value of IFS from the default white space to -. So $* interpreted sahil & suri as separate arguments & placed a – as the separator between them but $@ did not.

$?

This isn’t an argument supplied to a shell script. But I felt the need to mention this anyway in this article. The $? variable stores the exit status of the immediately executed command.An exit status of zero indicates successful execution of the program whereas a non-zero exit status indicates an unsuccessful execution. For example

[root@sahil-centos ~]# ls /
bin boot cgroup check_dir dev etc home lib lib64 lost+found media mnt opt Packages proc quadstor R_D root sbin selinux srv sys tmp usr var
[root@sahil-centos ~]# echo $?
0
[root@sahil-centos ~]# ls /sahil
ls: cannot access /sahil: No such file or directory
[root@sahil-centos ~]# echo $?
2

The $? variable is perhaps one of the most frequently used special variable in shell scripting or at the command line in general. We frequently use the value of $? in our shell scripts to modify the behavior of the script based on the success or failure of a command invocation. / Bash Shell Positional Parameters /

Conclusion

In this article, we explained how we can make use of bash shell positional parameters and special variables within our shell scripts to add more functionality and implement interesting ideas and logic within our scripts. We hope you’ve found the article fruitful and we welcome your feedback.

Related Article

Real time cpu utilization monitoring

Select command to make menu’s

Learn Linux

Thanks for your wonderful Support and Encouragement

Sahil Suri

I am a system administrator who loves to learn and share my knowledge with the community. I've been working in the IT industry since 2011.

Leave a Reply

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