Bash Functions

LINUX
FUNDAMENTALS
A Complete Guide for Beginners Enroll Course Now

Almost every programming language offers the flexibility of creating user-defined functions. Bash is no different. Users can create their functions in Bash by grouping commands under a single name. This guide will unravel the syntax of Bash function, the scope of variables within and outside of a Bash function and how to pass arguments to a function to make it compact and efficient.

What is Bash Function?

Bash functions are a set of commands, necessary loops or control statements grouped together for a particular task. This set of commands can be executed later using a single name. Whenever the name of a function is called as a simple command name, the whole set of commands written in the function is executed. Bash functions are executed in the current shell session. It doesn’t require starting a new process to interpret them.

How to Define a Function in Bash?

It is possible to define a Bash function in multiple formats. The basic syntax includes the function name followed by parentheses and a code block enclosed in curly braces:

function_name () {
  # Code block or Compound Commands
}

To write the whole function in a single line use the following format:

function_name () { commands; }
Note:

Redirections can also be added to redirect the output of a function:

function_name () {compound-command;} [ redirections ]

[ redirections ] is optional. However, any redirections specified with the shell function are performed when the function is executed.

Alternatively, the word function is reserved for creating a function in Bash. To declare a function use the reserved word function before the function name like the syntax below:

function function_name() {
# Code block or Compound Commands
}

If the reserved word function is used, but the parentheses are not supplied, the braces are recommended like the above syntax. A compact version of the syntax looks like the following:

function function_name { commands; }

Once a function is defined, call it like any other Bash command. In the following script, the hello function is called by writing hello after defining the function:

#!/bin/bash

hello () {
echo "hello, Linux users. Welcome to Linuxsimply"
}

# Call the function
hello

A simple Bash function

Naming Rule of Bash Function

  • The function name must be a valid shell name and shouldn’t match with the special Bash builtins.
  • By default, a function name can be any unquoted shell word that doesn’t contain the special symbol of expansion “$”.
  • In Bash, a function with the same name as a system command can override the command.

Variable Scope in Bash Function

Variable scope in programming languages refers to the portion of a program where a particular variable can be accessed. Usually, a variable that is declared inside a function is considered a local variable. On the other hand, variables outside of a function are considered global. However, in Bash scripting variables are by default global no matter whether they are defined inside or outside of a function. To make a local variable, supply the keyword local before the name of the variable. Look at the example below for a better understanding:

#!/bin/bash

num1=15 #global variable
num2=30 #global variable

var_changer(){
num1=45 #global variable changed
local num2=60 #set local variable
echo "Inside function num1 is: $num1"
echo "Inside function num2 is: $var2"
}

echo "Before executing function num1: $var1"
echo "Before executing function num2: $var2"

# Call the function
var_changer

echo "After executing function num1: $var1"
echo "After executing function num2: $var2"
EXPLANATION

The num1 and num2 are two global variables initially set to 15 and 30 respectively.

Then inside the var_changer function the global variable num1 is changed to 45. Moreover, the function sets a local variable num2.

Variable scope in Bash functionFrom the output, it can be concluded that a global variable can be accessed and changed within a function. This modification persists inside the function and even after the execution of the function. For instance, the num1 variable was initially set to 15. The function var_changer changed the value of num1 and set it to 45. After the execution of the function, it remains 45.

On the contrary, a local variable declared inside a function can be accessed within the function but is not available outside of it. Additionally, a local variable has precedence over a global variable if their names match. As evidence, consider the local variable num2, which matches the name of the global variable num2. When accessed within the function, it returns 60 instead of the global value of 30.

Scope of Variables for Multiple Bash Function

Bash uses dynamic scoping to control variables’s visibility within functions. In dynamic scoping, the visibility of variables depends on the sequence of function calls. The value of a variable is determined by its value in the calling function or the global scope at the time of the function call. The following script demonstrates the behavior of dynamic scoping and how it affects a variable’s visibility in nested child scopes:

#!/bin/bash

x=50
function f2() {
echo "Value of x inside f2: $x"
}

function f1() {
local x=30
echo "Value of x inside f1: $x"
f2
}

f1
EXPLANATION

In the above script, the function f1 declares a local variable x and sets its value to 30. Then it prints the value of the local variable. After that, it calls the function f2.

Function f2 prints the value of the variable again. As it is called within the scope of f1, it refers to the local variable x again.

Dynamic scope of variables in BashFrom the output, it is clear that even though the local variable x is declared in the f1 function, it is still visible in the f2 function. f1 didn’t refer to the global variable x as it is called within “f2”. However, if you call f2 outside of f1 then it will print the value of the global “x” which is 50.

Passing Arguments to a Bash Function

To pass arguments to a Bash function simply put them right after the function’s name when calling the function. The syntax is:

function_name argument

The welcome function of the following script requires an argument for proper execution:

#!/bin/bash

welcome () {
echo "Hello $1. Welcome to LinuxSimply"
}

welcome Anita
EXPLANATION

Here, “Anita” is the argument passed to the welcome function. The function utilizes this argument when it uses the positional parameter $1 to refer to the argument.

Passing argument to Bash functionThe program successfully prints a welcome message utilizing the argument “Anita”.

To supply multiple arguments to a function place them one after one separated by a space. It is highly recommended to use double quotes around the arguments to avoid mis-parsing. Look at the function below that takes multiple arguments:

#!/bin/bash

sum() {
result=$(( $1 + $2 ))
echo "Sum of the numbers: $result"
}

# Calling the function
sum "5" "7"
EXPLANATION

Two arguments "5" and "7" are supplied to the sum function. The function calls the arguments using the positional parameters $1 and $2 respectively.

Multiple arguments Bash functionThe program sums the provided arguments and prints the result of the summation.

A few key points on argument parsing in a Bash function are noted below:

  • The argument or parameters passed to a function can be accessed within the function by the positional parameters $1, $2, $3 … $n, corresponding to the position of the supplied argument.
  • $# contains the number of positional parameters passed to the function. For instance, the sum function discussed above has two arguments. If $# is accessed within the function it returns 2.
  • $0 contains the name of the command or script invoked. In the case of an interactive shell, $0 will contain the name of the shell (ex. bash), as it is the process name.
  • $* and $@ hold all the arguments passed to a function. When double-quoted, "$*" expands to a single string separated by space (Or by the first character of the IFS variable). For example, If the supplied arguments are $1, $2 … $n, "$*" expands to “$1 $2 … $n”. On the other hand, "$@" expands to separate strings containing the arguments. For instance, for the supplied arguments $1, $2 … $n, "$@" expands to “$1” “$2” … “$n”.

Return Values of Bash Functions

Bash scripting is different from regular programming languages in terms of the return value of a function. It doesn’t allow users to return the value of a variable like Python or C. Rather the return value of a Bash function is the exit status of the last executed command in the function. Hence the return value is zero for the successful execution of the last command or a numeric value within the range of 1-255 depending on the type of failure. The exit status is stored in the special variable $?. The return keyword is used to assign a return value as exit status in $?. Look at the following example related to the use of the reserved word return to set an exit status:

#!/bin/bash

return_value () {
echo "This is a function"
return 35
echo "The program should not go here"
}

# Call the function
return_value
echo $?
EXPLANATION

Here the return keyword is used to set the exit status 35. Whenever the function reaches the line of return command it immediately terminates. Any command or code written after the return command will not execute.

Return of a Bash functionAs expected, the function terminates before printing the message “The program should not go here”. Moreover, echo $? outputs that the current exit status is 35 as specified.

The default method Bash users choose to obtain the result of a function is by using the echo command to print the result at the last line of the function. Let’s have a simple example:

#!/bin/bash
multiply () {
    result=$(($1*$2))
    echo "The result of multiplication: $result"
}

# Call the function
multiply 50 2
EXPLANATION

Here, the result variable contains the desired output of the function. The echo command is used to print the result inside the function.

Echo return value within Bash functionAs expected, multiply 50 2 calls the multiply function. The function successfully prints the result of the multiplication.

Furthermore, redirection offers the option to redirect the output of the Bash function to a file. Look how I modified the above function to write the result in a file:

#!/bin/bash

multiply () {
result=$(($1 * $2))
echo "The result of multiplication: $result"
} > output.txt

# Call the function
multiply 50 2
EXPLANATION

> output.txt after the closing curly brace indicates that the output of the function is redirected to the output.txt file.

Redirect output of Bash function to fileOnce you run the script, the invoking of the function doesn’t show anything in the terminal. However, the content of the output.txt file proves that the output of the function is written in that file.

How to Call a Function in Bash?

To call a function, use the function name as a bash command. For example, let’s define the welcome function in the terminal:

welcome () {
echo "Hello $1. Welcome to LinuxSimply"
}

Defining welcome functionIt doesn’t show anything in the console. Now call the function using the function name welcome and provide the necessary argument:

welcome "Anita"
welcome "Laku"

Calling function by varying argumentAs you can see, the first call with the argument “Anita” prints a welcome message to Anita. In the second call, the welcome message changed due to the change in argument.

Note: Function definitions must precede their first call. Bash commands are interpreted from top to bottom. Hence there is no way in Bash to declare a function that is called before its creation.

If you have multiple definitions of a function with the same name, the last definition will override any previous ones.

func () {
echo "This is a function."
}

func () {
echo "This is another function"
}

func

Overriding function in BashHere, func is defined two times. Execution of func shows that the earlier version is shadowed and only the last definition is in effect.

How to Delete a Bash Function?

To delete a function use the unset command with the -f option. However, the -f option is not mandatory. It just indicates unsetting a function. So, the syntax can be:

unset -f function_name

Or,

unset function_name

Here’s a complete script:

# Define the function
func1() {
echo "This is my function"
}

# Call the function
func1

# Delete the function
unset -f func1

# Attempt to call the function after deletion
func1

unset -f func1 deletes the previously defined func1 function. Further attempts to execute func1 will result in an error.Deleting a Bash functionAs you see, the func1 function is no longer available after deleting it using the unset command.

Alias as Function in Bash

An alias in Bash is a shortcut for a command or a series of commands. It can be treated as a simple Bash function. To define an alias use the alias command. Here’s an example of how to create an alias:

alias update="sudo apt-get update && sudo apt-get upgrade"
EXPLANATION

In this example, the alias named update is created to perform both the package list update and upgrade commands in one go. After defining this alias, you can simply type update in the terminal to execute both commands.

alias as a function in BashAfter defining the alias the short and simple word update executes both commands sudo apt-get update and sudo apt-get upgrade.

Why Use Bash Functions?

Though Bash is a command-based language, Bash functions are still useful to perform complex operations with simplified code. The main advantages of functions in Bash are:

  1. Reusability: Functions are such a powerful program that you can use them as many times as you want. This saves time by eliminating the effort of writing the same code again and again. Moreover, it gives room to scriptwriters to write optimized code after a couple of iterations.
  2. Modularity: Modularity is one of the major advantages that Bash functions can offer. This way numerous scripts can be organized easily and efficiently. So that programmers can readily add new features to the existing code. Moreover, deletion or modification of scripts can be made without making any hodgepodge.
  3. Readability: Functions make the bash scripts more readable. Once the codes are broken down into smaller and more manageable pieces, it enhances the readability. Each function does a specific task while having a descriptive name that indicates its role. Functions help to understand scripts written by distant persons and fix the bugs in them.

Conclusion

In conclusion, there are lots of things to learn about bash functions. This article tries to give an exhaustive idea about the topic. I hope it helps to define a bash function and use it whenever necessary. If you are interested more about Bash function read our other articles in this section. Keep exploring.

People Also Ask

How to define a function in Bash?

The simplest syntax to define a Bash function is as follows:

function_name() {
# code goes here
}

How do I run a Bash function?

To run or call a Bash function use the function name. If you define your function from the terminal, simply writing the function name in the terminal invokes the function execution. On the contrary, if you define your function within a bash script you can call the function in that script like a bash command. Then executing the script from the terminal provides the expected result of the bash function.

Does Bash support recursive functions?

Yes. Bash supports recursive functions. It means you can define a function that calls itself within its own definition. However, the level of recursion may be limited. Fortunately, you can adjust that limit. But keep in mind that your definition avoids infinite recursion.

What is the purpose of FUNCNEST variable?

The FUNCNEST variable in Bash is used to control the maximum function nesting level. If set to a numeric value greater than 0, invocation that exceeds the value causes termination of the command.

Is the “function” keyword equivalent to parentheses when defining a function in Bash?

Yes, you can think function keyword as equivalent to parentheses when defining a function. But accurately speaking they are just alternative ways to define function.

Do I need to give a space after the curly brace while writing the function body?

If the function keyword is not specified, then it is recommended to keep a space after the curly brace while writing the body of the function. Because character after curly brace can expand to brace expansion. So better to leave a space after the curly brace to prevent brace expansion.

Can a bash function be defined using the same name of a system command?

Yes. You can define a function with the same name as a system command. However, it can override the system command. Better to choose other names reflecting the purpose or functionality of the function. Use of meaningful names to make your code more readable and maintainable is recommended.

Related Articles


<< Go Back to Bash Scripting Tutorial

5/5 - (8 votes)
Md Zahidul Islam Laku

Hey, I'm Zahidul Islam Laku currently working as a Linux Content Developer Executive at SOFTEKO. I completed my graduation from Bangladesh University of Engineering and Technology (BUET). I write articles on a variety of tech topics including Linux. Learning and writing on Linux is nothing but fun as it gives me more power on my machine. What can be more efficient than interacting with the Operating System without Graphical User Interface! Read Full Bio

Leave a Comment