Topic 11
FUNCTIONS
5/14/2021
Your first shell function
You can create a function within the shell as well as within a bash script
$ hello() { echo ‘Hello world!’; }
$ hello
Output:
Hello World
Note: You need the semi-colon when defining command line functions.
1
Passing arguments to a function
We can pass in arguments to function just like we pass arguments to a script
$ hello() { “Hello $1, welcome to CS18!.”;} $ hello Juan
Sample output:
Hello Juan, welcome to CS18!
5/14/2021
Displaying functions
To display defined functions use the declare command.
$ declare –F
Sample output:
declare -f command_not_found_handle
declare -f dequote
declare -f hello
declare -f quote
declare -f quote_readline
2
Display function source code
To view the function names and the source code use the –f option To view all of the functions:
$ declare –f
Or
$ declare –f | less
To specify a specific function:
$ declare –f hello
For more info: $ help declare
5/14/2021
Removing shell functions
You can remove shell functions by using the unset command
$ unset –f hello
$ hello
Output:
Command ‘hello’ not found, but can be installed
3
Defining Functions
To define a function we use the following syntax:
name() compound_command
OR
function name { #more common in ksh shell but works in bash too command1
command2 }
OR
function name() { ## bash-only hybrid command1
command2 }
5/14/2021
Defining Functions – one line syntax
One line functions inside{ …} must end with a semicolon:
function name { command1; command2; command;}
OR
name() { command1; command2; command;}
4
Writing functions
Functions definitions should appear at the beginning of the script.
You can create a functions file to store functions that you regularly use.
◦ /etc/init.d/functions is the default functions file which contains functions to be used by most or all shell scripts in the /etc/init.d directory. This file can be loaded as needed.
All shell functions are treated as a command.
You must load a function file at the start of a script using source or (.) command:
. /path/to/functions.sh
OR
source /path/to/functions.sh
You can call a function like a normal command.
5/14/2021
Passing arguments into a function
Just like bash scripts, shell functions have their own command line arguments. We can use $1, $2, … $n to access the arguments passed into the function.
$0 points to the shell script name, not the function name
$* or $@ holds all parameters or arguments passed to the function
$# holds the number of positional parameters passed to the function
To display the function name, use the array variable FUNCNAME, which contains the names of all shell functions currently in the execution stack. Variable exists only when a shell function is running.
5
5/14/2021
#!/bin/bash
# write a function
fresh(){
# t stores $1 argument passed to fresh() t=$1
echo “fresh(): \$0 is $0”
echo “fresh(): \$1 is $1”
echo “fresh(): \$t is $t”
echo “fresh(): total args passed to me $#”
echo “fresh(): all args (\$@) passed to me -\”$@\”” echo “fresh(): all args (\$*) passed to me -\”$*\””
}
# invoke the function with “Tomato” argument
echo “**** calling fresh() 1st time ****” fresh Tomato
# invoke the function with total 3 arguments echo “**** calling fresh() 2nd time ****” fresh Tomato Onion Paneer
#!/bin/bash
# funcback.sh : Use $FUNCNAME backup(){
local d=”$1″
[[ -z $d ]] && { echo “${FUNCNAME}(): directory name not specified”; exit 1; }
echo “Starting backup…”
}
backup $1
6
#!/bin/bash
file=”$1″
# User-defined function
is_file_dir(){
}
# $f is local variable
local f=”$1″
# file attributes comparisons using test i.e. [ … ]
[ -f “$f” ] && { echo “$f is a regular file.”; exit 0; }
[ -d “$f” ] && { echo “$f is a directory.”; exit 0; }
[ -L “$f” ] && { echo “$f is a symbolic link.”; exit 0; }
[ -x “$f” ] && { echo “$f is an executeble file.”; exit 0; }
# make sure filename supplied as command line arg else die
[ $# -eq 0 ] && { echo “Usage: $0 filename”; exit 1; }
# invoke the is_file_dir and pass $file as arg
is_file_dir “$file”
5/14/2021
Run as follows:
./cmdargs.sh /etc/resolv.conf ./cmdargs.sh /bin/date ./cmdargs.sh $HOME ./cmdargs.sh /sbin
Sample outputs:
/etc/resolv.conf is a regular file.
/bin/date is a regular file.
/home/vivek is a directory.
/sbin is a directory.
7
Local variables
By default all variables are global.
Modifying a variable in a function changes it in the whole script.
5/14/2021
Returning from a function
Bash functions, unlike functions in most programming languages do not allow you to return a value to the caller.
When a function ends its return value is its status: zero for success, non-zero for failure
Bash has a return statement, but we can only specify the function’s status, which is a numeric value like specified with return statements.
◦ Status value stored in $?
◦ If function does not return a value, its status is set based on the status of the last statement executed in
the function.
A few options for returning values
◦ Set a global variable with the result
◦ Use command substitution
◦ Pass in the name of a variable to use as the result variable
8
Returning from a function – global variable
Simplest way to return a value from a function is to just set a global variable to the result. Recall that in bash variables are global by default.
function myfunc()
{
myresult=‘some value’ }
myfunc
echo $myresult
5/14/2021
Returning from a function – local variables
Global variables in large programs will lead to difficult to find bugs.
Better approach is to use local variables, but then how do you get the result to the caller. You can use command substitution
function myfunc() {
local myresult=‘some value’
echo “$myresult”
}
result=$(myfunc) #or result=`myfunc` echo $myresult
9
Returning from a function – passing in a variable
The other way is to write your function so that it accepts a variable name as part of its command line and then set that variable to the result of the function.
function myfunc()
{
local _resultvar=$1
local myresult=‘some value’ eval $__resultvar=“’$myresult’”
}
myfunc result
echo $result
5/14/2021
10