Similar to other programming languages, you can make and use functions in Bash as well. However, Bash functions are their own breed and are somewhat limited in functionality compared to other programming languages.
In this article, we’re going over the basics of a Bash function, so you can get started writing better shell scripts.
Also read: Bash ‘if else’ statement examples
Defining Bash functions
Bash functions are defined exactly how you’d expect a function to be defined. There are, however, two different approaches to defining a function.
The first format is the one you’ll be more familiar with if you’ve been coding in just about any language.
function_name () {
commands
}
The second format is more specific to Bash.
function function_name {
commands
}
There are no technical differences between the two, and you can pick whatever method you prefer. As you’d normally expect, the code between the curly braces acts as the body of the function and contains the commands that a given function will execute.Â
Function definitions must be placed before you call the function. If done the other way around, your script won’t even see the function in the first place. Also, defining a function doesn’t automatically execute one. You’ll have to invoke the function in the shell script.
Another thing to keep in mind is that when you’re writing a function in a single line, otherwise known as compacted functions, make sure to put a semi-colon (;) after the last command.
Let’s take a look at a very simple example.
#!/bin/bash
hello_world () {
echo 'hello, world'
}
hello_world
The above function will print ‘hello, world’ every time you invoke it in a shell script. Just like functions are, you can invoke one as many times as you’d like.Â
Also read: How to compare Strings in Bash?
Variable Scopes
If you’ve been coding in just about any other language, you already know what this means. For those of you who don’t, each time you declare a variable, it gets a scope — global or local.
A global variable can be accessed from anywhere in the program, regardless of its place of definition. On the other hand, a local variable can only be used in the function it has been defined.Â
In Bash, all variables are global by default. If you want to declare a local variable, you must use the local keyboard before the variable’s name.
#!/bin/bash
var1='A'
var2='B'
newFunc () {
local var1='C'
var2='D'
echo "newFunc: var1: $var1, var2: $var2"
}
echo "Before executing function: var1: $var1, var2: $var2"
newFunc
echo "After executing function: var1: $var1, var2: $var2"
In the above Bash script, the variables, var1 and var2, are declared at first and are global in nature. However, our newFunc() function declares a local var1 which can only be accessed inside the function and changes the value of var2 from ‘B’ to ‘D’.
Note: When a local variable is set inside a function’s body and has the same name as a global variable, it prioritises the global variable. Another thing to keep in mind is that you can change global variables from inside a function.Â
Also read:Â What port does SFTP use? How to change the SFTP port?
Returning values from Bash functions
Unlike regular programming languages, Bash functions don’t return values. Instead, a Bash function returns the exit code of the last executed command by the script.
If the command runs successfully, the return value is zero; otherwise, you get a numerical error code between 1-255. The return status is defined by using the return keyword and can be assigned to the $? variable. Also, keep in mind that using the return keyword will terminate the function.Â
#!/bin/bash
newFunc () {
echo "Task executed"
return 55
}
newFunc
echo $?
The above script will print ‘Task executed’ followed by 55 as specified by the return statement. If you’re looking to return an arbitrary value, we will have to use another way.
One way of doing this is to assign the result of the function to a global variable. You can then equate the function to the variable in the script and have it return whatever you want.Â
#!/bin/bash
my_function () {
func_result="Task complete"
}
my_function
echo $func_result
The above script prints ‘Task complete’ when called. This isn’t exactly returning a value per se, but it allows you to get arbitrary values out of a function.
Another way of doing this is to send the return value to stdout using either echo or printf.
#!/bin/bash
my_function () {
local func_result="some result"
echo "$func_result"
}
func_result="$(my_function)"
echo $func_result
Instead of executing the function, which will print the message to stdout, we’re assigning the function output to the func_result variable using $() command substitution. You can use this variable later on if you need.
Also read: How to exit Bash script?
Passing arguments
Passing arguments to Bash functions is rather simple. All you have to do is put them after the function’s name, separated by a space. Be sure to enclose your arguments in double quotes to avoid misparsing an argument with spaces.Â
#!/bin/bash
greeting () {
echo "Hello $1"
}
greeting "Joe"
In the above example, we can pass an argument to our greeting function by mentioning it in front of the function name during invocation.Â
Here are few things you should keep in mind when passing arguments to your functions.
- The passed parameters are parsed in order of their position corresponding to the function’s name.
- $0 variable is reserved for function names.
- The $# variable holds the number of positional arguments passed to a particular function.
- The $* and $@ variables hold all positional arguments passed to a particular function.
- When double-quoted, “$#” expands to a string separated by spaces (“$1 $2 $3”).
- When double-quoted, “$@” expands to separate strings (“$1” “$2” “$3”).
- When not double-quoted, both variables are identical.
Also read:Â Bash While loop explained