Pass arguments into a function

From Linux Bash Shell Scripting Tutorial Wiki
Jump to navigation Jump to search

← Calling functionsHomelocal variable →

Let us see how to pass parameters to a Bash function.

  • A shell function is nothing but a set of one or more commands/statements that act as a complete routine.
  • Each function must have a unique name.
  • Shell functions have their own command line argument or parameters.
  • Use shell variable $1, $2,..$n to access argument passed to the function.

Passing parameters to a Bash function

  • The syntax is as follows to create user-defined functions in a shell script:
function_name(){
   command_block_here
}
## OR ##
function function_name_here(){
   command_line_block
}
## passing parameters to a Bash function ##
my_function_name(){
  arg1=$1
  arg2=$2
  command on $arg1
}

Invoke function

  • To invoke the the function use the following syntax:
 my_function_name foo bar

Where,

  1. my_function_name = Your function name.
  2. foo = Argument # 1 passed to the function (positional parameter # 1).
  3. bar = Argument # 2 passed to the function.

Examples

Create a function called fresh.sh:

#!/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

Save and close the file. Run it as follows:

chmod +x fresh.sh
./fresh.sh

Sample outputs:

**** calling fresh() 1st time ****
fresh(): $0 is ./fresh.sh
fresh(): $1 is Tomato
fresh(): $t is Tomato
fresh(): total args passed to me 1
fresh(): all args ($@) passed to me -"Tomato"
fresh(): all args ($*) passed to me -"Tomato"
**** calling fresh() 2nd time ****
fresh(): $0 is ./fresh.sh
fresh(): $1 is Tomato
fresh(): $t is Tomato
fresh(): total args passed to me 3
fresh(): all args ($@) passed to me -"Tomato Onion Paneer"
fresh(): all args ($*) passed to me -"Tomato Onion Paneer"

Let us try one more example. Create a new shell script to determine if given name is file or directory (cmdargs.sh):

#!/bin/bash
# Name - cmdargs.sh
# Purpose - Passing positional parameters to user defined function 
# -----------------------------------------------------------------
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"

Run it 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.


Function shell variables

  • All function parameters or arguments can be accessed via $1, $2, $3,..., $N.
  • $0 always point to the shell script name.
  • $* or $@ holds all parameters or arguments passed to the function.
  • $# holds the number of positional parameters passed to the function.

How do I display function name?

$0 always point to the shell script name. However, you can use an array variable called FUNCNAME which contains the names of all shell functions currently in the execution call stack. The element with index 0 is the name any currently-executing shell function.This variable exists only when a shell function is executing.

FUNCNAME in action

Create a shell script called funcback.sh:

#!/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

Save and close the file. Run it as follows:

chmod +x funcback.sh
funcback.sh /home
funcback.sh

Sample outputs:

backup(): directory name not specified

Return values

It is possible to pass a value from the function back to the bash using the return command. The return statement terminates the function. The syntax is as follows:

return
return [value]

One can force script to exit with the return value specified by [value]. If [value] is omitted, the return status is that of the last command executed within the function or script.

Examples

Create a new file called math.sh:

#!/bin/bash
#!/bin/bash
# Name - math.sh
# Purpose - Demo return value 
# ------------------------------------

## user define function
math(){
	local a=$1
	local b=$2
	local sum=$(( a + b))
	return $sum
}

## call the math function with 5 and 10 as  arguments 
math 5 10

## display back result (returned value) using $?
echo "5 + 10 = $?"

Run it as follows:

chmod +x math.sh
./math.sh
The return statement stops the math() and passes a value back to the calling script
The return statement stops the math() and passes a value back to the calling script

The above example is straightforward. The return command returns any given value between zero (0) and 255. By default, the value passed by the return statement is the current value of the exit status variable. For example, the following code will return wrong values as it is not between zero (0) and 255.

math 500 100

Here is the proper use of return command (bash-task.sh):

#!/bin/bash
# Name: bash-task.sh
# Purpose: Check if a file exists or not using custom bash function and return value
# -----------------------------------------------------------------------------------

# set values 
readonly TRUE=0
readonly FALSE=1

# get input from the CLI
file="$1"

# return $TRUE (0) if file found 
# return $FALSE (1) if file not found
is_file_found(){
	[ -f "$1" ] && return $TRUE || return $FALSE
}

# show usage info if $1 not passed to our script
if [ $# -eq 0 ]
then
	echo "Usage: $0 filename"
	exit 1
fi

# let us call our function 
is_file_found "$file"

# take action based upon return value
if [ $? -eq 0 ]
then
	echo "$file added to backup task"
else
	echo "$file not found."
fi

Run it as follows:

chmod +x bash-task.sh
./bash-task.sh
./bash-task.sh /etc/passwd
./bash-task.sh /foo/bar
Passing parameters to a Bash function and return true or false value

How to return custom value from a user-defined function?

As I said earlier, you can't use return command. However, the workaround is as following using the printf command/echo command:

#!/bin/bash
#!/bin/bash
# Name - math.sh
# Purpose - Demo how to return custom value 
# -----------------------------------------

## user define function that use echo/printf 
math(){
	local a=$1
	local b=$2
	local sum=$(( a + b))
	echo $sum
}

## call the math function with 5 and 10 as  arguments 
total=$(math 500 42)

## display back result (returned value) using $?
echo "500 + 42 = $total"

Listing functions

Use the typeset command or declare command.

Show the known functions and their code/definitions

Open the terminal and then run:

declare -f
declare -f function_name_here
## or ##
typeset -f
typeset -f function_name_here

How to remove or unset functions

Use the unset command to unset values and attributes of shell variables and functions:

unset -f function_name_here
unset -f foo
unset -f bar

← Calling functionsHomelocal variable →