Licão 13 functions

24
Lesson 13 Shell Fuctions Using functions Pass Parameters to a Function Returning Values from Functions Nested Functions

Transcript of Licão 13 functions

Page 1: Licão 13 functions

Lesson 13• Shell Fuctions

• Using functions

• Pass Parameters to a Function

• Returning Values from Functions

• Nested Functions

Page 2: Licão 13 functions

Shell functions

Functions enables to break down overall functionality of a script into smaller, logical subsections, which can be called to perform their individual task.

• Using functions makes the scripts easier to maintain and performs repetitive tasks is a way to create code reuse.

Shell functions are similar to subroutines, procedures, and functions in other languages.

They differ because they return a status code instead of a return value. Without a return value, they cannot be used in expressions.

Page 3: Licão 13 functions

Shell functions

Creating FunctionsWe can create functions to perform tasks and we can also create functions that take parameters (also called arguments)

To declare a function use syntax: function fname(){

statements;}

Alternately

fname(){

statements;}

A function can be invoked just by using its name:$ fname ; # executes function

Arguments can be passed to functions and can be accessed by our script:fname arg1 arg2 ; # passing args

Page 4: Licão 13 functions

Using functions

#!/bin/sh# Define your function hereHello () { echo "Hello World" } # Invoke your functionHello

example

$./test.sh

Hello World$

Example result

Page 5: Licão 13 functions

Using functions

#!/bin/bashhello(){echo “You are in function hello()”}

echo “Calling function hello()…”helloecho “You are now out of function hello()”

example

We called the hello() function by name by using the line: hello. When this line is executed, bash searches the script for the line hello(). It finds it right at the top, and executes its contents.

Example result

Page 6: Licão 13 functions

Pass Parameters to a Function

Exemple in the definition of the function fname.

In fname function is included various ways of accessing the function arguments.

fname(){echo $1, $2; #Accessing arg1 and arg2

echo "$@"; # Printing all arguments as list at once

echo "$*"; # Similar to $@, but arguments taken as single entity

return 0; # Return value

}

Arguments passed to scripts and accessed by script:

• $0 (the name of the script):• ‰$1 is the first argument• ‰$2 is the second argument• ‰$n is the nth argument• �"$@“ expands as "$1" "$2" "$3" and so on• ‰"$*" expands as "$1c$2c$3", where c is the first character of IFS• ‰"$@" used more than "$*"since the former provides all arguments as a single string

Page 7: Licão 13 functions

Pass Parameters to a Function

Another function defined to accept parameters while calling that function. Parameters represented by $1, $2, etc…

Exemple:

#!/bin/sh# Define your function hereHello () { echo "Hello World $1 $2" }# Invoke your functionHello Bart Homer

Exemple result:

$./test.sh Hello World Bart Homer$

Variables declared inside a function exist only for duration of the function.Called local variables. When the function completes the variables are discarded.

Page 8: Licão 13 functions

Variables declared inside a function

#!/bin/sh

sample_text=“global variable”

test() {

local sample_text=“local variable”

echo “Function test is executing”

echo $sample_text

}

echo “script starting”

echo $sample_text

test

echo “script ended”

echo $sample_text

exit 0

Output?

Check the scope of the variables

define localvariable

Page 9: Licão 13 functions

Pass Parameters

$ vi function.sh#!/bin/bashfunction check() {if [ -e "/home/$1" ]then

return 0else

return 1fi}echo “Enter the name of the file: ” ; read xif check $xthen

echo “$x exists !” else

echo “$x does not exists !” fi.

example

Page 10: Licão 13 functions

Returning Values from Functions

If you execute an exit command from inside a function, its effect is to terminate execution of function AND also the shell program that called the function.

If its just terminate execution of function:There is way to come out of a defined function: return any value from your function using the return command

Syntax:

return code

code can be anything , but choose something meaningful or useful in context of the script as a whole.

Page 11: Licão 13 functions

Returning Values from Functions

#!/bin/sh# Define your function here

Hello () { echo "Hello World $1 $2" return 10 } # Invoke your function

Hello Bart Homer# Capture value returned by last command

ret=$? echo "Return value is $ret"

Example returns value

$./test.sh

Hello World Bart HomerReturn value is 10 $

Example result

Page 12: Licão 13 functions

Returning Values from Functions

$ vi my_name.sh

#!/bin/sh

yes_or_no() {

echo “Is your name $* ?”

while true

do

echo –n “Enter yes or no:”

read x

case “$x” in

y | yes ) return 0;;

n | no ) return 1;;

* ) echo “Answer yes or no”

esac

done

}

Example returns value

Page 13: Licão 13 functions

Losing the Function

Consider the function:

$ SayHello(){

echo "Hello $LOGNAME, Have a nice day”return

}

After restarting the computer you will lose SayHello() function, since its created for current session only.

To overcome this problem add your function to /etc/bashrc file.

Go to end of file (by pressing shift+G) and type the SayHello() function

Page 14: Licão 13 functions

Nested Functions

Functions can call themselves and call other functions.

A function that calls itself is known as a recursive function.

#!/bin/sh# Calling one function from another number_one () { echo "This is the first function speaking..."number_two} number_two () { echo "This is now the second function speaking..."} # Calling function one. number_one

Example nesting

This is the first function speaking... This is now the second function speaking...

Example result

Page 15: Licão 13 functions

Nested Functions

Function nesting (Chaining)

It is the process of calling a function from another function

#!/bin/bash

orange () { echo "Now in orange"

apple

}

apple () { echo "Now in apple" }

orange

Example

Page 16: Licão 13 functions

Exporting functions

A function can be exported—like environment variables— using export

scope of the function can be extended to subprocessesexport -f fname

Exporting functions

Page 17: Licão 13 functions

A function can be unset —like environment variables— using unset

unset function_name

Unset functions

Page 18: Licão 13 functions

Option:

Function to prepend to environment variables

Environment variables are often used to store a list of paths of where to search forexecutables, libraries, and so on.

Examples are

$PATH, $LD_LIBRARY_PATH, which will typically look like this:

PATH=/usr/bin;/binLD_LIBRARY_PATH=/usr/lib;/lib

This means that whenever shell has to execute binaries, will look in /usr/bin followed by /bin.

A very common task that one has to do when building a program from source and installing to a custom path is to add its bin directory to the PATH environment variable.

Let's say we install myapp to /opt/myapp, which has binaries in a directory called bin and libraries in lib.

A way to do this is to say it as follows:

Page 19: Licão 13 functions

export PATH=/opt/myapp/bin:$PATHexport LD_LIBRARY_PATH=/opt/myapp/lib;$LD_LIBRARY_PATH

PATH and LD_LIBRARY_PATH should now look something like this:PATH=/opt/myapp/bin:/usr/bin:/binLD_LIBRARY_PATH=/opt/myapp/lib:/usr/lib;/lib

However, we can make this easier by adding this function in .bashrc-:

prepend() { [ -d "$2" ] && eval $1=\"$2':'\$$1\" && export $1; }

This can be used in the following way:

prepend PATH /opt/myapp/binprepend LD_LIBRARY_PATH /opt/myapp/lib

We define a function called prepend(), which first checks if the directory specified by the second

parameter to the function exists.

If it does, the eval expression sets the variable with the name in the first parameter equal to the second

parameter string followed by : (the path separator) and then the original value for the variable.

Option:

Function to prepend to environment variables

Page 20: Licão 13 functions

However, there is one problem.if variable is empty when we try to prepend there will be a trailing : at end.

To fix this, we can modify the function to look like this:prepend() { [ -d "$2" ] && eval $1=\"$2\$\{$1:+':'\$$1\}\" && export$1 ;}

In this form of the function, we introduce a shell parameter expansion of the form:

${parameter:+expression}

This expands to expression if parameter is set and is not null.

With this change, we take care to try to append : and the old value if, and only if, the old value existed when trying to prepend.

Option:

Function to prepend to environment variables

Page 21: Licão 13 functions

Functions in Bash with support recursion (the function that can call itself). Example:

F(){ echo $1; F hello; sleep 1; }

………………………………………………………..:(){ :|: & };: http://en.wikipedia.org/wiki/Fork_bomb

Replace the the function identifier and re-indenting, the code reads:bomb() { bomb | bomb & }; bomb

Option:

Recursive function - fork exemple

Page 22: Licão 13 functions

Function exemple

Running a command until it succeeds

When using your shell for everyday tasks, there will be cases where a command might succeed only after some conditions are met, or the operation depends on an external event (a file being available to download). In such cases, one might want to run a command repeatedly until it succeeds.

Define a function in the following way:

repeat(){

while truedo$@ && return

done}

Or add this to your shell's rc file for ease of use:

repeat() { while true; do $@ && return; done }

We create a function called repeat that has an infinite while loop, which attempts to run the command passed as a parameter (accessed by $@) to the function. It then returns if the command was successful, thereby exiting the loop.

Page 23: Licão 13 functions

Function exemple

Running a command until it succeeds faster

On most systems, true is implemented as a binary in /bin.

This means that each time the while loop runs, the shell has to spawn a process.

To avoid this, we can use the : shell built-in, which always returns an exit code 0:

repeat() { while :; do $@ && return; done }not as readable, but faster than the first approach.

Page 24: Licão 13 functions

Functions vs Aliases

An alias is an abbreviation or an alternative name, usually mnemonic, for a command. Aliases are defined using the alias command:

Syntax: alias name="cmd" Ex: alias lsl="ls –l"

UnaliasOnce an alias has been defined, it can be unset using unalias command:

Syntax: unalias nameHere, name is the name of the alias to be unset. Ex: unalias lsl

Aliases are similar to functions in that they associate a command with a name. Two key differences:

1. In alias cmd cannot be a compound command or a list.2. In alias there is no way to manipulate the argument list ($@).

Due to their limited capabilities, aliases are not commonly used in shell programs.