Like any other scripting languages, Bash also supports functions. Let's see how to define and use functions.
A function can be defined as follows:
function fname() { statements; }
Or 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
Following is the definition of the function fname
. In the fname
function, we have 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 }
Similarly, arguments can be passed to scripts and can be 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"
, wherec
is the first character of IFS"$@"
is the most used one."$*"
is used rarely since it gives all arguments as a single string.
Let's explore more tips on Bash functions.
Functions in Bash also support recursion (the function that can call itself). For example, F() { echo $1; F hello; sleep 1; }
.
Tip
Fork bomb
:(){ :|:& };:
This recursive function is a function that calls itself. It infinitely spawns processes and ends up in a denial of service attack. &
is postfixed with the function call to bring the subprocess into the background. This is a dangerous code as it forks processes and, therefore, it is called a fork bomb.
You may find it difficult to interpret the above code. See Wikipedia page http://en.wikipedia.org/wiki/Fork_bomb for more details and interpretation of the fork bomb.
It can be prevented by restricting the maximum number of processes that can be spawned from the config file /etc/security/limits.conf
.
A function can be exported like environment variables using export
such that the scope of the function can be extended to subprocesses, as follows:
export -f fname
We can get the return value of a command or function as follows:
cmd; echo $?;
$?
will give the return value of the command cmd
.
The return value is called exit status. It can be used to analyze whether a command completed its execution successfully or unsuccessfully. If the command exits successfully, the exit status will be zero, else it will be non-zero.
We can check whether a command terminated successfully or not as follows:
#!/bin/bash #Filename: success_test.sh CMD="command" #Substitute with command for which you need to test exit status $CMD if [ $? –eq 0 ]; then echo "$CMD executed successfully" else echo "$CMD terminated unsuccessfully" fi
Arguments to commands can be passed in different formats. Suppose –p
and -v
are the options available and -k NO
is another option that takes a number. Also the command takes a filename as argument. It can be executed in multiple ways as follows:
$ command -p -v -k 1 file
Or:
$ command -pv -k 1 file
Or:
$ command -vpk 1 file
Or:
$ command file -pvk 1