How to build a Shell Script Library

Many of the scripts in this page have been written as functions rather than as stand-alone scripts so that they can be easily and gracefully incorporated into other scripts without incurring the overhead of making system calls. While there's no #include feature in a shell script, as there is in C, there is a tremendously important capability called sourcing a file that serves the same purpose.

To see why this is important, let's consider the alternative. If you invoke a shell script within a shell, by default that script is run within its own subshell. You can immediately prove this experimentally:

$ cat tinyscript.sh
test=2
$ test=1
$ tinyscript.sh
$ echo $test
1

Because this script changed the value of the variable test within the subshell running the script, the value of the existing test variable in the current shell's environment was not affected. If you instead use the "." source notation to run the script, it is handled as though each command in the script was typed directly into the current shell:

$ . tinyscript.sh
$ echo $test
2

As you might expect, if you have an exit 0 command within a script that's sourced, for example, it will exit that shell and log out of that window.

The Code
To turn the functions in this page into a library for use in other scripts, extract all the functions and concatenate them into one big file. If we call this file library.sh, a test script that accesses all of the functions might look like this:

#!/bin/sh

# Library test script

. library.sh

initializeANSI

echon "First off, do you have echo in your path? (1=yes, 2=no) "
read answer
while ! validint $answer 1 2 ; do
echon "${boldon}Try again${boldoff}. Do you have echo "
echon "in your path? (1=yes, 2=no) "
read answer
done

if ! checkForCmdInPath "echo" ; then
echo "Nope, can't find the echo command."
else
echo "The echo command is in the PATH."
fi

echo ""
echon "Enter a year you think might be a leap year: "
read year

while ! validint $year 1 9999 ; do
echon "Please enter a year in the ${boldon}correct${boldoff} format: "
read year
done

if isLeapYear $year ; then
echo "${greenf}You're right! $year was a leap year.${reset}"
else
echo "${redf}Nope, that's not a leap year.${reset}"
fi

exit 0

Notice that the library is incorporated, and all functions are read and included in the run-time environment of the script, with the single line

. library.sh

This is a useful approach in working with the many scripts in this book, and one that can be exploited again and again as needed.

Running the Script
To run the test script given in the previous section, simply invoke it at the command line.

The Results
$ library-test
First off, do you have echo in your path? (1=yes, 2=no) 1
The echo command is in the PATH.
Enter a year you think might be a leap year: 432423
Your value is too big: largest acceptable value is 9999
Please enter a year in the correct format: 432
You're right! 432 was a leap year.

On your computer screen, the error messages just shown will be a bit more blunt because their words will be in bold, and the correct guess of a leap year will be displayed in green