Understanding and Writing functions in Shell Scripts – Part VI

Functions play an important role in any programming language. Like many real programming languages, bash has functions which are used with limited implementation.

Shell Scripting Functions
Understanding Linux Shell Script Functions

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?

  1. It helps us to reuse the code.
  2. Improve the readability of program.
  3. Efficient use of variables inside the program.
  4. Allows us to test the program part by part.
  5. 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.

  1. Understand Basic Linux Shell Scripting Language Tips – Part I
  2. 5 Shell Scripts for Linux Newbies to Learn Shell Programming – Part II
  3. Sailing Through The World of Linux BASH Scripting – Part III
  4. Mathematical Aspect of Linux Shell Programming – Part IV
  5. 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.

Hey TecMint readers,

Exciting news! Every month, our top blog commenters will have the chance to win fantastic rewards, like free Linux eBooks such as RHCE, RHCSA, LFCS, Learn Linux, and Awk, each worth $20!

Learn more about the contest and stand a chance to win by sharing your thoughts below!

Anoop C S
I am basically a FOSS enthusiast interested in working under GNU/Linux and system administration. Looking forward to becoming a part of an open source initiative. Currently, pursue Computer Science & Engineering.

Each tutorial at TecMint is created by a team of experienced Linux system administrators so that it meets our high-quality standards.

Join the TecMint Weekly Newsletter (More Than 156,129 Linux Enthusiasts Have Subscribed)
Was this article helpful? Please add a comment or buy me a coffee to show your appreciation.

4 Comments

Leave a Reply

Got Something to Say? Join the Discussion...

Thank you for taking the time to share your thoughts with us. We appreciate your decision to leave a comment and value your contribution to the discussion. It's important to note that we moderate all comments in accordance with our comment policy to ensure a respectful and constructive conversation.

Rest assured that your email address will remain private and will not be published or shared with anyone. We prioritize the privacy and security of our users.