MoreBash:Functions - Introduction

From Juneday education
Jump to: navigation, search

Work in progress

This chapter is a work in progress. Remove this section when the page is production-ready.

Introduction

This chapter introduces functions in Bash.

We are working on videos. After reading, move on to the exercises (link at the bottom).

If you want to, you can read the bonus advanced example here below after seeing the videos (but it is probably best if you do the exercises first).

Don't worry if you don't understand the advanced example on this page. It is advanced and it is not important to understand. We added it as a challenge for those who really wants a challenge to understand an advanced use of scripts and functions. Most scripts and functions in Bash are not as complicated as the bonus example below!!!

Videos

Bonus! Simulating call-by-reference (Advanced!)

Optional reading for those who wants to challenge themselves with an advanced example, after seeing the videos and finishing all the exercises.

Did you know that you can write a bash function which alters the value of a variable given as argument, as if it were called by-reference?

Idea: Write a function which takes a string argument and makes the first letter of the string upper case, without echoing or returning anything. The script should be called like this:

$ ./uc_first.sh rikard
Rikard
$ ./uc_first.sh henrik
Henrik

The trick is to call the function, not with the value of the variable, but the variable name. In the script, we save $1 (the argument to the script) in a variable called string. The function is named uc_first(). We call the function with the name of the string variable:

string=$1
uc_first string
echo $string

The function now gets as argument the name of the variable we want to change outside the function. In order to do this, we create a variable with the value $string inside the script.

This is done like this:

varname=\$"$1"

If we call the function with the value "string", varname then gets the value $string. This we'll use later.

Now, we need the value of the external variable string. We obtain that like this:

str=`eval "expr \"$varname\""`

We evaluate the expression "whatever value varname has". Now, varname actually had the value $string and when we evaluate "$string", we get the contents of this external (to the function) variable!

Now, we fix a string variable called res with the value of $string but with the first letter as upper case:

first=${str:0:1}
upper=$(echo $first|tr [a-z] [A-Z])
res=$upper${str:1}

The only remaining step is to re-assign the external variable string to the value of res:

eval $1=\$res

That expression, when evaluated will read: string=WhateverUppercaseFixedStringWeGotAsArgument.

Here's the full script source code:

#!/bin/bash

##################################################
# Inspired by Advanced Bash-Scripting Guide:     #
# Chapter 24. Functions                          #
# Example 24-5.                                  #
# Dereferencing a parameter passed to a function #
#                                                #
# http://tldp.org/LDP/abs/html/complexfunct.html #
##################################################
#set -x
uc_first(){
    # create a variable of value '$string'
    varname=\$"$1" 
    # Get the value of the variable $string
    # the value is the string given as arg to the script
    str=`eval "expr \"$varname\""`
    # str now contains whatever the argument was
    
    # Fix upper case first
    first=${str:0:1}
    upper=$(echo $first|tr [a-z] [A-Z])
    res=$upper${str:1}
    
    # Change the value of the variable string to res
    eval $1=\$res
    # evaluates to:
    # string=$res
    # which sets the external variable string to
    # the fixed upper case version
}
string=$1
uc_first string
echo $string

Let's run the script with the argument henrik and see all the steps:

$ ./uc_first.sh henrik
+ string=henrik
+ uc_first string
# here the function code starts!
+ varname='$string'
++ eval 'expr "$string"'
+++ expr henrik
# save the value of the variable string:
+ str=henrik
# fix the upper case:
+ first=h
++ echo h
++ tr '[a-z]' '[A-Z]'
+ upper=H
+ res=Henrik
# change the external variable string:
+ eval 'string=$res'
++ string=Henrik
# here we have left the function and we echo the string value
# which has now been changed by the script!
+ echo Henrik
Henrik

Slides and videos

  • Slides for the lecture: Functions in Bash PDF
  • Videos: TODO!

Links

External links

Source code

  • [TODO Github link for functions introduction]

Chapter links

Next page contains exercises (if any).

« PreviousBook TOCNext »