≡ Menu

Bash Shell Functions Tutorial with 6 Practical Examples

Bash shell functions are a way to group several UNIX / Linux commands for later execution using a single name for the group. Bash shell function can be executed just like a regular Unix command. Shell functions are executed in the current shell context without creating any new process to interpret them.

Both bash aliases and functions allow you to define shortcuts for longer or more complicated commands. However, aliases don’t allow control-flows, arguments, and other trickery things these functions will allow as explained in this tutorial.

This article is part of the on-going bash tutorial series. Refer to our earlier tutorial about bash introduction, bash exist status and bash alias examples.

Syntax to create a bash function:

function functionname()
{
commands
.
.
}
  • function is a keyword which is optional.
  • functionname is the name of the function
  • commands – List of commands to be executed in the functions.

Function accepts arguments. During execution, the arguments to the function becomes the positional parameters. Positional parameter 0 will have the scriptname which remains unchanged.

You can call the bash function from the command line as shown below:

$ functionname arg1 arg2
  • When shell interprets a Linux command, it first looks into the special built-in functions like break, continue, eval, exec etc., then it looks for shell functions.
  • The exit status of the bash function is the exit status of the last command executed in the function body.

Note: Place the shell function definitions in a shell start up file (for example, .bash_profile ). This way, the shell function is always available for you from the command line. Refer to our earlier bash execution sequence article to identify when .bash_profile will get executed.

Example 1: Function to display long list of files with the given extension

The function “lsext” is used to find the list of files in the current directory, which has the given extension as shown below. This function uses the combination of find command and ls command to get the job done.

$ function lsext()
{
find . -type f -iname '*.'${1}'' -exec ls -l {} \; ;
}

$ cd ~

$ lsext txt
-rw-r--r-- 1 root root   24 Dec 15 14:00 InMorning.txt
-rw-r--r-- 1 root root  184 Dec 16 11:45 Changes16.txt
-rw-r--r-- 1 root root  458 Dec 18 11:04 Changes18.txt
-rw-r--r-- 1 root root 1821 Feb  4 15:01 ChangesOfDB.txt

Example 2. Bash Function to execute a given Linux command on a group of files

In the following example, function “batchexec” finds the files with the given extension and executes the given command on those selected files.

$ function batchexec()
{
find . -type f -iname '*.'${1}'' -exec ${@:2}  {} \; ;
}

$ cd ~

$ batchexec sh ls

$ batchexec sh chmod 755

$ ls -l *.sh
-rwxr-xr-x 1 root root  144 Mar  9 14:39 debug.sh
-rwxr-xr-x 1 root root 5431 Jan 25 11:32 get_opc_vers.sh
-rwxr-xr-x 1 root root   22 Mar 18 08:32 t.sh

In the above example, it finds all the shell script files with the .sh extension, and changes its permission to 755. (All permission for user, for group and others read and execute permission). In the function definition you could notice “${@:2}” which gives the second and following positional parameters (shell expansion feature).

Example 3. Bash Function to generate random password

The following function is used to generate the random strong passwords with special character for the given length. If length is not given by default it generates with 12 characters length.

$ function rpass() {
        cat /dev/urandom | tr -cd '[:graph:]' | head -c ${1:-12}
}

$ rpass 6
-Ju.T[[

$ rpass
Gz1f!aKN^""k

In the above example, when rpass is executed with the argument 6, it generates random password with 6 characters and rpass without argument generates 12 character length password. ${1:-12} means if $1 is unset or null 12 will be returned else value of $1 will be substituted.

Example 4. Bash function to get IP address of a given interface

The following example defines a function called ‘getip’ which accepts interface name as an argument, and gives the IP address assigned on the given interface in the machine. ( by default it returns eth0 ip address ). This uses the ifconfig command to get the ip-address.

$ function getip()
{
/sbin/ifconfig ${1:-eth0} | awk '/inet addr/ {print $2}' | awk -F: '{print $2}';
}

$ getip
15.110.106.86

$ getip eth0
15.110.106.86

$ getip lo
127.0.0.1

Example 5. Bash function to print the machines details

This example defines the function which gives all the required information about the machine. Users can define and call this function in the start up files, so that you will get these information during startup.

$ function mach()
{
    echo -e "\nMachine information:" ; uname -a
    echo -e "\nUsers logged on:" ; w -h
    echo -e "\nCurrent date :" ; date
    echo -e "\nMachine status :" ; uptime
    echo -e "\nMemory status :" ; free
    echo -e "\nFilesystem status :"; df -h
}

$ mach
Machine information:
Linux dev-db 2.6.18-128.el5 #1 SMP Wed Dec 17 11:41:38 EST 2008 x86_64 GNU/Linux

Users logged on:
root     pts/2    ptal.mot Wed10    0.00s  1.35s  0.01s w -h

Current date :
Thu Mar 18 11:59:36 CET 2010

Machine status :
 11:59:36 up 7 days, 3 min,  1 user,  load average: 0.01, 0.15, 0.15

Memory status :
             total       used       free     shared    buffers     cached
Mem:       2059768    2033212      26556          0      81912     797560
-/+ buffers/cache:    1153740     906028
Swap:      4192956      48164    4144792

Filesystem status :
Filesystem            Size  Used Avail Use% Mounted on
/dev/sda1              12G   12G     0 100% /
tmpfs                1006M  377M  629M  38% /dev/shm
/dev/sdc5             9.9G  409M  9.0G   5% /mydisk

Example 6: Bash function to format ls output better

The following function will clear the screen, place the cursor at the top of the screen, executes ls, and then places the cursor at the end of the screen.

$ function ll ()
{
    clear;
    tput cup 0 0;
    ls --color=auto -F --color=always -lhFrt;
    tput cup 40 0;
}

$ ll

Display the function code using type command

type is a shell built-in used to view the function code.

Syntax:
type function-name
$ type ll
ll is a function
ll ()
{
    clear;
    tput cup 0 0;
    ls --color=auto -F --color=always -lhFrt;
    tput cup 40 0;
    alias ls="ls --color=auto -F"
}

For your easy reference, get all the 6 functions mentioned this article from this sample .bash_profile functions file.

Add all these functions to your ~/.bash_profile file, to make sure you have access to these functions all the times without having to create it every time.

Add your comment

If you enjoyed this article, you might also like..

  1. 50 Linux Sysadmin Tutorials
  2. 50 Most Frequently Used Linux Commands (With Examples)
  3. Top 25 Best Linux Performance Monitoring and Debugging Tools
  4. Mommy, I found it! – 15 Practical Linux Find Command Examples
  5. Linux 101 Hacks 2nd Edition eBook Linux 101 Hacks Book

Bash 101 Hacks Book Sed and Awk 101 Hacks Book Nagios Core 3 Book Vim 101 Hacks Book

Comments on this entry are closed.

  • Chris F.A. Johnson April 21, 2010, 8:17 am

    The syntax you use to define functions is a bash-only hybrid. The standard syntax (which will work in all Bourne-type shells) is:

    function_name() COMPOUND_COMMAND [optional redirection]

    The KornShell syntax (which does not work in all shells) is:

    function function_name COMPOUND_COMMAND [optional redirection]

  • Alpha April 21, 2010, 1:39 pm

    re: Example 3. Bash Function to generate random password

    I was wondering why using /dev/random instead of /dev/urandom
    FAILS — although the former seems more secure,
    according to:
    http://en.wikipedia.org/wiki//dev/random

    Thanks kindly for your reply.

  • Rubem April 22, 2010, 12:18 pm

    I think it’s great article.
    Please. I wondering why anyone talk about PAM autentication? Publish something about it. at a same quality of present article.

  • gus3 April 23, 2010, 3:18 pm

    @Chris Johnson: Bash-only syntax is to be expected in an article titled, “Bash Shell Functions…”

    @Alpha: Using /dev/urandom does not deplete the entropy pool for services which need real randomness (such as SSL/TLS encryption negotiation). “Strong password” does not automatically equal “entropy”. An example would be taking the phrase “I Love Lucy” and turning it into “;L0v3Loos3e”. It is a strong password, with all four character types (upper- and lower-case, digits, and punctuation), but it is hardly random.

  • don taber April 24, 2010, 8:23 am

    My favorite is a floating point version of expr that can handle math & trig functions. It fires off Perl for each instance so it is not something you’d use where speed is a concern.

    fpexpr ()
    {
    echo “$*” | perl -ne ‘use Math::Trig; print eval($_),”\n” ;’
    }

  • The Hulk April 25, 2010, 3:13 pm

    This is one of the greatest sites on the web (for Linux-heads).

  • Chris F.A. Johnson April 25, 2010, 6:04 pm

    @gus3, why would anyone use syntax that is more verbose and less useful than the standard syntax, which works perfectly well in bash — and all other Bourne-type shells?

  • Zartan April 26, 2010, 2:19 pm

    I suspect the author is using /dev/urandom instead of /dev/random because cat will try to fill an entire stdio buffer before passing it on to tr. Even a 4K buffer would easily empty /dev/random’s entropy pool, then hang waiting for more. Using “cat -u” would work better, but still would read too much.

    Better to limit the amount read by using dd. Since tr is discarding characters outside the printable ASCII character set, get four times as many as needed:

    len=${1:-12}
    if [ “0$len” -le 1 ]
    then
    len=12
    fi
    dd if=/dev/urandom bs=$(expr 4 \* $len) count=1 | tr -cd ‘[:graph:]’ | head -c $len
    }

  • Zartan April 26, 2010, 2:21 pm

    Sigh. I forgot to redirect dd’s statistics on stderr. Try this:

    dd if=/dev/urandom bs=$(expr 4 \* $len) count=1 2> /dev/null | tr -cd ‘[:graph:]‘ | head -c $len

  • shweta October 26, 2012, 2:40 am

    fun1(){ x=100000; echo “In fun1() x = $x ” ; }
    fun2(){ y=200000; echo “In fun2() y = $y ” ; }

    x=100 ; y=200
    echo ” Before calling d fun1() x=$x”
    echo -e $(fun1)
    echo ” After calling d fun1() x=$x”
    echo ” Before calling d fun2() y=$y”
    fun2
    echo ” After calling d fun2() y=$y”

    output :
    Before calling d fun1() x=100
    In fun1() x = 100000
    After calling d fun1() x=100
    Before calling d fun2() y=200
    In fun2() y = 200000
    After calling d fun2() y=200000

    The value of x doesn’t chamge, but the value of y change, what is the diff b/w these to calling $(fun1) or fun1…. .. i m a beginner in shell programming pls help me

  • Chris F.A. Johnson October 26, 2012, 7:20 am

    $(fun1) is executed in a subshell and cannot chage any values in the rest of the script.

  • Sergio Luiz Araujo Silva July 19, 2014, 5:57 pm

    We can know if are using eth0 or wlan0 with the command route, isn’t it?

    myip=$(ifconfig $(route | awk ‘$4==”UG” {print $8}’) | awk ‘/inet/ {print “ip address: ” $2″ mask: “$4}’)

    echo ${myip?We are offline now, please contact technical support}

  • Dick Guertin January 30, 2016, 10:23 am

    Example 4 did not work for me. I found the following worked:

    #!/bin/bash
    function getip()
    {
    /sbin/ifconfig ${1:-en0} | awk ‘/inet / {print $2}’;
    }
    getip $1
    exit 0

    I made that an executable script called “funtest”,
    and executed it as “funtest” and “funtest lo0”.