Shell Functions

ShellShellBeginner
Practice Now

Introduction

In this lab, we will explore shell functions in Linux. Shell functions are reusable blocks of code that perform specific tasks, making our scripts more organized and efficient. We'll learn how to create, call, and use functions with parameters in shell scripts. This lab is designed for beginners, so we'll take it step by step and explain each concept thoroughly.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL linux(("`Linux`")) -.-> linux/BasicSystemCommandsGroup(["`Basic System Commands`"]) linux(("`Linux`")) -.-> linux/BasicFileOperationsGroup(["`Basic File Operations`"]) shell(("`Shell`")) -.-> shell/BasicSyntaxandStructureGroup(["`Basic Syntax and Structure`"]) shell(("`Shell`")) -.-> shell/VariableHandlingGroup(["`Variable Handling`"]) shell(("`Shell`")) -.-> shell/ControlFlowGroup(["`Control Flow`"]) shell(("`Shell`")) -.-> shell/FunctionsandScopeGroup(["`Functions and Scope`"]) shell(("`Shell`")) -.-> shell/AdvancedScriptingConceptsGroup(["`Advanced Scripting Concepts`"]) linux/BasicSystemCommandsGroup -.-> linux/echo("`Text Display`") linux/BasicFileOperationsGroup -.-> linux/touch("`File Creating/Updating`") linux/BasicFileOperationsGroup -.-> linux/chmod("`Permission Modifying`") shell/BasicSyntaxandStructureGroup -.-> shell/comments("`Comments`") shell/VariableHandlingGroup -.-> shell/variables_decl("`Variable Declaration`") shell/VariableHandlingGroup -.-> shell/variables_usage("`Variable Usage`") shell/ControlFlowGroup -.-> shell/case("`Case Statements`") shell/FunctionsandScopeGroup -.-> shell/func_def("`Function Definition`") shell/AdvancedScriptingConceptsGroup -.-> shell/arith_expansion("`Arithmetic Expansion`") shell/AdvancedScriptingConceptsGroup -.-> shell/cmd_substitution("`Command Substitution`") subgraph Lab Skills linux/echo -.-> lab-388818{{"`Shell Functions`"}} linux/touch -.-> lab-388818{{"`Shell Functions`"}} linux/chmod -.-> lab-388818{{"`Shell Functions`"}} shell/comments -.-> lab-388818{{"`Shell Functions`"}} shell/variables_decl -.-> lab-388818{{"`Shell Functions`"}} shell/variables_usage -.-> lab-388818{{"`Shell Functions`"}} shell/case -.-> lab-388818{{"`Shell Functions`"}} shell/func_def -.-> lab-388818{{"`Shell Functions`"}} shell/arith_expansion -.-> lab-388818{{"`Shell Functions`"}} shell/cmd_substitution -.-> lab-388818{{"`Shell Functions`"}} end

Creating Your First Shell Function

Let's start by creating a simple shell function. Shell functions are like mini-scripts within a larger script, allowing you to group commands that perform a specific task.

First, we need to create a new file. Open your terminal and type:

cd ~/project
touch functions.sh

This command changes to the project directory and creates a new file called functions.sh. This file will contain our shell functions.

Now, let's add our first function:

#!/bin/bash

## This is a simple function
greet() {
  echo "Hello, World!"
}

## This line calls (runs) the function
greet

Let's break this down:

  • The first line #!/bin/bash is called a shebang. It tells the system to use bash to interpret this script.
  • We define our function with greet() { }. Everything between the curly braces is part of the function.
  • Inside the function, we have a simple echo command that prints "Hello, World!".
  • The last line greet calls (runs) our function.

Now, let's make our script executable and run it:

chmod +x functions.sh
./functions.sh

You should see:

Hello, World!

If you don't see this output, double-check that you've typed everything correctly in the functions.sh file.

Functions with Parameters

Now that we've created a basic function, let's make it more flexible by adding parameters. Parameters allow us to pass information into our functions.

Open the functions.sh file again, and replace the content with the following code:

#!/bin/bash

## Function with a parameter
greet() {
  echo "Hello, $1!"
}

## Function with multiple parameters
calculate() {
  echo "The sum of $1 and $2 is $(($1 + $2))"
}

## Call functions with arguments
greet "Alice"
calculate 5 3

Let's examine this code:

  • In the greet function, $1 refers to the first argument passed to the function.
  • In the calculate function, $1 and $2 refer to the first and second arguments, respectively.
  • $(($1 + $2)) performs arithmetic addition of the two parameters.
./functions.sh

You should see:

Hello, Alice!
The sum of 5 and 3 is 8

If you don't see this output, make sure you've saved the changes to the file correctly.

Return Values from Functions

In shell scripting, functions don't return values in the same way as in other programming languages. Instead, they can either echo a result that can be captured, or they can modify a global variable. Let's explore both methods.

Open functions.sh again, and update the content with the following code:

#!/bin/bash

## Function that echoes a result
get_square() {
  echo $(($1 * $1))
}

## Function that modifies a global variable
RESULT=0
set_global_result() {
  RESULT=$(($1 * $1))
}

## Capture the echoed result
square_of_5=$(get_square 5)
echo "The square of 5 is $square_of_5"

## Use the function to modify the global variable
set_global_result 6
echo "The square of 6 is $RESULT"

Let's break this down:

  • get_square function uses echo to output the result, which we capture using $() syntax.
  • set_global_result function modifies the global variable RESULT.
  • We use $() to capture the output of get_square into a variable.
  • We call set_global_result, which modifies RESULT, and then we print RESULT.

Save the file and run it:

./functions.sh

You should see:

The square of 5 is 25
The square of 6 is 36

If you don't see this output, double-check your functions.sh file for any typos.

Understanding Variable Scope

In shell scripts, variables are global by default. This means they can be accessed from anywhere in the script. However, you can use the local keyword to create variables that are only accessible within a function. This is called local scope.

Let's modify our functions.sh file to demonstrate this concept.

Update the content with the following code:

#!/bin/bash

## Global variable
GLOBAL_VAR="I'm global"

## Function with a local variable
demonstrate_scope() {
  local LOCAL_VAR="I'm local"
  echo "Inside function: GLOBAL_VAR = $GLOBAL_VAR"
  echo "Inside function: LOCAL_VAR = $LOCAL_VAR"
}

## Call the function
demonstrate_scope

echo "Outside function: GLOBAL_VAR = $GLOBAL_VAR"
echo "Outside function: LOCAL_VAR = $LOCAL_VAR"

Here's what's happening in this script:

  • We define a global variable GLOBAL_VAR.
  • Inside the demonstrate_scope function, we define a local variable LOCAL_VAR using the local keyword.
  • We print both variables inside the function.
  • After calling the function, we try to print both variables again outside the function.

Save the file and run it:

./functions.sh

You should see output similar to this:

Inside function: GLOBAL_VAR = I'm global
Inside function: LOCAL_VAR = I'm local
Outside function: GLOBAL_VAR = I'm global
Outside function: LOCAL_VAR =

Notice that LOCAL_VAR is empty when accessed outside the function. This is because local variables are only accessible within the function where they are defined.

Advanced Function - ENGLISH_CALC

Now that we've covered the basics of shell functions, let's create a more advanced function called ENGLISH_CALC. This function will take three arguments: two numbers and an operation (plus, minus, or times).

Replace the content with the following code:

#!/bin/bash

ENGLISH_CALC() {
  local num1=$1
  local operation=$2
  local num2=$3
  local result

  case $operation in
    plus)
      result=$((num1 + num2))
      echo "$num1 + $num2 = $result"
      ;;
    minus)
      result=$((num1 - num2))
      echo "$num1 - $num2 = $result"
      ;;
    times)
      result=$((num1 * num2))
      echo "$num1 * $num2 = $result"
      ;;
    *)
      echo "Invalid operation. Please use 'plus', 'minus', or 'times'."
      return 1
      ;;
  esac
}

## Test the function
ENGLISH_CALC 3 plus 5
ENGLISH_CALC 5 minus 1
ENGLISH_CALC 4 times 6
ENGLISH_CALC 2 divide 2 ## This should show an error message

Let's break down this function:

  • We use local variables to store our inputs and results. This is good practice to avoid interfering with any global variables.
  • We use a case statement to handle different operations. This is similar to a switch statement in other languages.
  • For each valid operation, we perform the calculation and echo the result.
  • If an invalid operation is provided, we echo an error message and return 1 (in shell scripts, a non-zero return value indicates an error).
  • At the end, we test our function with various inputs, including an invalid operation.

Save the file and run it:

./functions.sh

You should see the following output:

3 + 5 = 8
5 - 1 = 4
4 * 6 = 24
Invalid operation. Please use 'plus', 'minus', or 'times'.

If you don't see this output, double-check your functions.sh file for any typos.

Summary

In this lab, we explored shell functions in Linux, starting from the basics and progressing to more advanced concepts. We learned how to:

  1. Create and call simple functions
  2. Work with function parameters
  3. Return values from functions using echo and global variables
  4. Understand variable scope and use local variables
  5. Create a more complex function that processes arithmetic operations

Shell functions are powerful tools that can help you write more organized, efficient, and reusable code. They allow you to break down complex scripts into smaller, manageable pieces, making your scripts easier to understand and maintain.

By mastering shell functions, you'll be able to write more sophisticated shell scripts and automate complex tasks more effectively in a Linux environment. Remember, practice is key to becoming proficient with shell scripting. Try modifying the functions we've created or create your own to solve specific problems you encounter in your work with Linux.

Other Shell Tutorials you may like