Functions play an important role in any programming language. Like many real programming languages, bash has functions which are used with limited implementation.
What are functions?
In programming, functions are named sections of a program that performs a specific task. In this sense, a function is a type of procedure or routine. When a function is called the program leaves the current section of code and begins to execute the first line inside the function. Whenever there is repetitive code or when a task repeats, consider using a function instead.
For example, consider the case where we need to find the factorial of a number at several stages of a particular program. Instead of writing the whole code (for calculating the factorial) each and every time, we can write that part of code which calculates the factorial once inside a block and reuse the same at multiple occasions.
Why do we write functions?
- It helps us to reuse the code.
- Improve the readability of program.
- Efficient use of variables inside the program.
- Allows us to test the program part by part.
- Displays program as a bunch of sub-steps.
Functions in shell scripts
The general syntax for writing functions in shell script includes the following ways.
function func_name { . . . commands . . . } or func_name ( ) { . . . commands . . . } Opening curly braces can also be used in the second line as well. func_name ( ) { . . . commands . . . }
You are always free to write valid commands inside these function blocks as we do normally in shell scripts. Now let’s try to write one simple script with a small function inside it.
#!/bin/bash call_echo ( ) { echo ‘This is inside function’ } op=$1 if [ $# -ne 1 ]; then echo "Usage: $0 <1/0>" else if [ $1 = 0 ] ; then echo ‘This is outside function’ elif [ $1 = 1 ] ; then call_echo else echo ‘Invalid argument’ fi fi exit 0
The function definition must precede the first call to it. There is nothing like ‘declaring the function’ before calling it. And we can always nest functions inside functions.
Note:- Writing empty functions always results in syntax errors.
When same function is defined multiple times, the final version is what is invoked. Let’s take an example.
#!/bin/bash func_same ( ) { echo ‘First definition’ } func_same ( ) { echo ‘Second definition’ } func_same exit 0
Functions taking parameters and returning values
Let’s get deeper by considering functions taking parameters and returning values. To return a value from a function we use the ‘return’ shell built-in. Syntax is as follows.
func_name ( ) { . . . commands . . . return $ret_val }
Similarly we can pass arguments to the functions separated with spaces as given below.
func_name $arg_1 $arg_2 $arg_3
Inside the function we can access the arguments in order as $1, $2, $3 and so on. Look at the following example script to find the maximum of two integers using function to add more clarity.
#!/bin/bash USG_ERR=7 max_two ( ) { if [ "$1" -eq "$2" ] ; then echo 'Equal' exit 0 elif [ "$1" -gt "$2" ] ; then echo $1 else echo $2 fi } err_str ( ) { echo "Usage: $0 <number1> <number2>" exit $USG_ERR } NUM_1=$1 NUM_2=$2 x if [ $# -ne 2 ] ; then err_str elif [ `expr $NUM_1 : '[0-9]*'` -eq ${#NUM_1} ] ; then if [ `expr $NUM_2 : '[0-9]*'` -eq ${#NUM_2} ] ; then max_two $NUM_1 $NUM_2 else err_str fi else err_str fi exit 0
The above looks like a bit complex, but it’s simple if we read through the lines. First nested if-else if lines for validation purposes i.e., to check number and type of arguments with the help of regular expressions. After that we call the function with two command line arguments and displays the result there itself. This is because we cannot return large integers from a function. Another way to work around this problem is to use global variables to store the result inside function. The script below explains this method.
#!/bin/bash USG_ERR=7 ret_val= max_two ( ) { if [ "$1" -eq "$2" ] ; then echo 'Equal' exit 0 elif [ "$1" -gt "$2" ] ; then ret_val=$1 else ret_val=$2 fi } err_str ( ) { echo "Usage: $0 <number1> <number2>" exit $USG_ERR } NUM_1=$1 NUM_2=$2 if [ $# -ne 2 ] ; then err_str elif [ `expr $NUM_1 : '[0-9]*'` -eq ${#NUM_1} ] ; then if [ `expr $NUM_2 : '[0-9]*'` -eq ${#NUM_2} ] ; then max_two $NUM_1 $NUM_2 echo $ret_val else err_str fi else err_str fi exit 0
Now try out some exciting problems that were explained in the previous shell scripting series using functions as follows.
- Understand Basic Linux Shell Scripting Language Tips – Part I
- 5 Shell Scripts for Linux Newbies to Learn Shell Programming – Part II
- Sailing Through The World of Linux BASH Scripting – Part III
- Mathematical Aspect of Linux Shell Programming – Part IV
- Calculating Mathematical Expressions in Shell Scripting Language – Part V
I will get back with more insight to functional features like using local variables, recursion etc in the next part. Stay updated with comments.
Play around with basic shell commands(especially the shell buit-ins) to become familiar with shell. Mode of scripting is just as simple as programming. Try out the pdf from the following link.
https://drive.google.com/file/d/0BzU05gnqHz5mSThlZFFwZjdMcm8/edit?usp=sharing
It will help you to step into the world of shell scripting.
Good luck. . .
Hi…
Am new for shell and how to become master in Shell scripting.
kid keep trying and failing and you will be become master in shell scripting there is no shortcut..
@Hans,
Thanks for motivating and supporting our readers, it will help them to boost their learning process..