Using Bash Functions to Structure Scripts
January 12, 2020
Function Structure
Let’s start by examining the basic format of a bash function with the following example:
#!/bin/bash
sum() {
echo $(( $1 + $2 ))
}
sum 1 4
# 5
The sum function is declared with a name, two parentheses, and curly braces that wrap the function code body. Similar to regular bash commands/scripts it can be passed arguments, which are referenced positionally ($1, $2).
Output Redirect
Besides using functions to reduce code complexity and duplication, one of the main use cases for using a bash function would be to customize output redirection. Say you had a bash script where you had a function whose output didn’t matter to the end user - you could redirect the output of that particular function to /dev/null
to silence its output while it performed its work. Here’s an example:
#!/bin/bash
noisy_work() {
not_a_real_command
} 2> /dev/null
sum() {
noisy_work
echo $(( $1 + $2 ))
}
sum 2 5
# 7
Note the 2> /dev/null
after the closing curly brace - what this is saying is:
when this function is invoked, redirect any standard error (2) to /dev/null
This effectively mutes the error that is raised when the not_a_real_command
command is attempted to be run. A real-world application of that concept may be to alter which commands get run depending on how the user’s environment has been set up (fall back to another command, etc.).
Return Values
By default, the return value of a bash function will be the value of the return value of the last command, and the return status will be the return status of the last command. To customize what the return value and status are you can use the return
keyword:
#!/bin/bash
sum() {
local result=$(($1 + $2))
echo $result
return $result
}
sum 1 4
# 5
Variable Scope
Lastly, function bodies can access global variables but can also declare their own variables local to the function scope. This can be achieved by using the “local” keyword as used in the previous code example.