Named parameters in Linux Bash scripts

There are basic positional parameters in bash scripts that might be the first way that one learns how to add parameters to bash scripts. However there should be a way to add named parameters to a script also, and to do so in a way in which it does not take to much time to do so. Often I want to write a bash script that preforms some kind of task other then that of parsing options.

Well in bash there is a built in command that might prove to be the first solution that comes to mind when it comes to having named parameters in a script. In this post I will be going over a few examples of that built in command, and also write about other topics that might come up in the process of doing so.

1 - Basic Named parameter examples using the getopts bash built in command

The bash command comes with a bunch of built in commands to preform a number of tasks. One such built in command is the getopts command that can be used to create named parameter options for a bash script. There are limitations with this command such as being limited to single character options for the script. However unless I am making a script that is fairly complex this option for named parameters should work okay in most situations.

1.1 - getopts parameters that expect an argument

If I want to add options that will take an argument after it is used then I will want to use a colon in the option string. When doing so there will be the variable that I use with the getopts command that will store the value of the current option that is being parsed as always. On top of the usual variable that will home the named parameter that was used the argument that was passed for the named option will be stored in a variable called OPTARG

1
2
3
4
5
6
7
8
9
10
#!/bin/bash
getopts ":f:" opt;
echo $opt
echo $OPTARG
if [ $opt = "f" ]; then
echo "file ${OPTARG} given"
cat ${OPTARG} | base32
fi

2 - getopts and a while loop

The getopts can be used in a while loop with a case statement. That is that there can be this while loop where I am looping calling the getopts command each time. On each loop the variable that I set with the getopts command will be updated with the current option name, and the /$OPTARG variable will be updated with the current argument for the current option if it is that kin d of option.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#!/bin/bash
## defaults
target="./project-folder"
mode="read"
while getopts ":t:m:" opt; do
case $opt in
t) target="$OPTARG"
;;
m) mode="$OPTARG"
;;
\?) echo "Invalid option -$OPTARG" >&2
;;
esac
done
echo " target folder: ${target}"
echo " mode: ${mode}"

3 - getopts wc script example

Now that I have covered the basics of the getopts bash built in command I should make at least one example that shows that this way of creating named parameters for bash scripts works okay. For this example I put together a simple script that will spit out the total word count for a collection of text files, or just concatenate them all which is the default behavior. This script will of course make use of the getopts bash built in, however I will also be making use of a bunch of other bash script features such as functions, conditional statements, and piping.

So when it comes to writing this kind of script there are a few options that I would like to have for such a script. One option is to be able to given the source folder to look at to find text files. Then it would also be nice to have another options that will set the mode of the script. That is that I would like to have more than one mode where the default mode will just concatenate all the files and spit out the result to the standard output, and the other will return a total word count for the collection of content. So then when it comes to this script I will want to have at least two named options one that might be -s that will be used to set the source folder to look in, and the other would be -m to set the mode.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#!/bin/bash
## defaults
source="./text-collection"
mode="cat"
while getopts ":s:m:" opt; do
case $opt in
s) source="$OPTARG"
;;
m) mode="$OPTARG"
;;
\?) echo "Invalid option -$OPTARG" >&2
;;
esac
done
catFiles(){
echo -n $(eval "ls ${source}/*.txt | xargs cat")
}
# mode: 'cat'
# in cat mode just concat the source files and spit out the result
# to the standard output
if [ $mode = "cat" ]; then
catFiles
echo ""
fi
# mode: 'wc'
# in wc mode give a word count
if [ $mode = "wc" ]; then
catFiles | wc -w
fi

So then this script seems to work as expected then when I just give it a source folder without any additional options it will just concatenate the files into one big body of text. However if I do set the mode to wc then it will give a grand total word count of that large body if text thanks to the Linux wc command.

The Linux wc command is a useful command for a wide range of reasons, as the name suggests it can be used to get a word count for a body of text. However it also has a number of other useful options that can be used to get a line count, or the size of the text in terms of bytes. However getting into the depth of the Linux wc command would be off topic.

4 - Conclusion

That is it for named parameters in bash shell scripts, when it comes to additional resources on bash the best option if of course the manual page on bash. The manual is very long, and does not include a lot of examples, which warrants a need for posts like this. Still the man page will cover the topic of named parameters with the getopts built in bash command, and a whole lot more in great detail.

When it comes to my content here there is my main post on bash scripts, but there is also my post on parameters in general in bash that might be worth checking out.