Learning never exhausts the mind
Home >  Technology > Linux > How to Create and Use Bash Scripts

Last Updated on by

Learn how to write Bash scripts on Unix/Linux, a required skill for system administration and a handy skill for the rest of us.
Introduction to Linux Series
  1. Installing Linux Step by Step
  2. Linux Tips for Beginners
  3. Beginners guide to Reading and Finding Files in Linux
  4. Using Grep to Search for Text in Linux
  5. Understanding Linux File Permissions
  6. How to Archive, Compress and Extract files in Linux
  7. Linux Piping and Redirection
  8. Linux Hardlinks and Softlinks
  9. How to Create and Use Bash Scripts
  10. Basic Data Recovery in Linux
  11. Apache Administration on Linux
  12. MySql Administration on Linux
  13. Switching from Windows to Linux

All Linux systems have a shell, the basic text-based user interface. Bash is one of the most popular and it stands for Bourne-Again SHell.

A Bash script is analogous to a DOS batch file. In it's simplest form you can run multiple commands one after another in sequence. Like DOS batch files you can build some pretty complex scripts given time. For now, we will look at how to create a few simple, useful, bash scripts.

Writing a simple Bash script

Each script starts with what's called a "shebang", followed by the path to the shell that you want the script to use.

#!/bin/bash

The "#!" characters are called the shebang.

Scripts usually have comments at the top which include author information, what the script does and usage instructions. Comments start with a hash - #.

#!/bin/bash

# This is a comment

Let's say we want to create a bash script to copy some PHP files from our user development directory to the webserver root. We could manually type in the command each time, or we can create a bash script and call that instead.

Create a new file using your favourite text editor (pico for me) and enter the following lines.

#!/bin/bash

cp *.php /usr/web/public_html

Save the file as something meaningful, for example publish and close the editor.

We now need to make this script executable by changing the Linux permissions.

chmod 700 publish

This will let you, and only you, read, write, and execute the script.

From within the directory you created the script in, you can enter publish on the command line and it will then execute the command to copy the files to the webserver.

Using Variables in a Bash script

Variables are a key component of programming. Variables allow a programmer to store data, alter and reuse them throughout the script.

There are two types of variables - system and user. System variables are created and maintained by the system. They are designated with CAPITAL letters. Some examples are:

  • USER: The current logged in user.
  • HOME: The current user's home directory.
  • HOSTNAME: The hostname of the computer at this time.
  • TERM: This specifies the type of terminal to emulate when running the shell.
  • MAIL: The path to the current user's mailbox.

User variables are ones you create inside your script specifically for your script and the cannot be accessed outside your script.

Never name your user/private variables using UPPERCASE characters. Uppercase variable names are reserved for internal shell variables, and you run a risk of overwriting them.

We can create a backup script which will backup the users home directory to /tmp/.

#!/bin/bash

# This bash script is used to back up a user's home directory to /tmp/.

user=$(whoami)
input=/home/$user
output=/tmp/${user}_home_$(date +%Y-%m-%d_%H%M%S).tar.gz

tar -czf $output $input
echo "Backup of $input completed!"

In this example, we can see that the user variable "user" has been used to capture the output from the whoami command. It is then appended to a string and assigned to the input variable. An output variable is then created which again does some string concatenation and formatting of dates.

Using variables like this makes scripts easier to write, read and maintain.

Finally, the command takes in the variables instead of one really long line which is difficult to read as it will probably span multiple lines.

Parameters and User Input in Bash Scripts

Scripts can take in a series of parameters from the user, for example, a filename or path.

In the command line parameters are added after the script name and are separated with a space.

Here is a simple bash script to show parameters read in and shown on the screen.

#!/bin/bash

echo $1 $2 $3

When run using script.sh aaa bbb ccc it will automatically assign 'aaa' to the variable $1, 'bbb' to $2 and 'ccc' to $3. You can then use these like any other variable.

Functions in Bash Scripts

Functions are small reusable blocks of code which perform one specific action. They can be called from multiple locations and prevent code duplication.

Functions in bash scripts are very similar to functions in other programming languages.

#!/bin/bash

showMessage

function showMessage() {
  echo "Hello World"
}

You can also pass parameters into function in the same way parameters are passed into a function

#!/bin/bash

showMessage "Hello World" "This is a message" 

function showMessage() {
  echo $1
  echo $2
}

If...Else...Conditional Statements in Bash Scripts

Sometimes it is necessary to check a condition before running a section of code, or running one bit of code in certain circumstances and another in a different set of circumstances.

A basic if statement effectively says, if a particular condition is true, then perform a given set of actions.

#!/bin/bash


if [ $1 -gt 100 ]
then
  echo That\'s a large number.
fi

When running this script and passing in a number, if the number is greater than 100 the script will output "That's a large number".

We can extend this to cover numbers less than 100 with a different message.

#!/bin/bash


if [ $1 -gt 100 ]
then
  echo That\'s a large number.
else
  echo That\'s a small number.
fi

Now if a number less than 100 is entered it will show "That's a small number".

We can also check another possibility, the user entered 100, and show another different message. In bash scripts, elif is short for else if.

#!/bin/bash


if [ $1 -gt 100 ]
then
  echo That\'s a large number.
elif [ $1 -lt 100 ]
  echo That\'s a small number.
else
  echo You entered 100.
fi

Maybe you need to check multiple conditions using boolean operators.

if [ $USER == 'tim' ] || [ $USER == 'lonewolf' ]
then
  ls -alh
else
  ls
fi

Looping and Iteration in Bash Scripts

Looping is very useful in any programming language. It lets you run a series of commands multiple times, usually over a collection of objects, for example, running a command for every file in a directory.

There are several different types of loop, I won't go into detail as to which one does what and when you should use one or the other. You can read more about looping in the article below.

While loop in Bash Script

The while loop is the easiest loop and works by evaluating a condition, similar to an if statement above, and if true runs a block of code. If the condition is still true it will run the code again, over and over, until the condition is false.

The basic syntax for a while loop is shown below. It will output the numbers 1 through 10 on the screen.

#!/bin/bash

# Basic while loop
counter=1
while [ $counter -le 10 ]
do
  echo $counter
  ((counter++))
done

It is important to remember that the condition must always evaluate to false at some point, otherwise, you will have an infinite loop. If you forgot to increment the counter in the loop above, the system would continue to count on the screen until it broke the system.

For loop in Bash Script

For loops are a little harder to write, but they are more flexible and there is much less chance that you will have an infinite loop.

The same counting script using a for loop is below. It's less code but harder to read if you're unfamiliar with the syntax.

for value in {1..10}
do
  echo $value
done

For loops can work on collections of anything, for example, an array of names.

#!/bin/bash

# Basic for loop
names='Brando Hopkins Caine'
for name in $names
do
  echo $name
done

Useful Bash Scripts

Here is a collection of some of my most useful bash scripts which you can download and use on your system.

Bash Script for Backup Files

This is my bash script for backing up my home NAS. It will first mount a USB3 external hard drive to /media/backup, then it will use rsync to backup the main NAS files, my home directory, apache and mysql directories. Finally it will run a mysqldump to backup my databases.

#!/bin/bash

sudo mount -t ext4 /dev/sdf1 /media/backup
sudo rsync -av /media/megadrive/files /media/backup/files
sudo rsync -av /home/timmy /media/backup/timmy
sudo rsync -av /etc/apache2 /media/backup/apache
sudo rsync -av /var/lib/mysql /media/backup/mysql/data

sudo mysqldump -uroot -p<password> mastersystem | bzip2 -c > /media/backup/mysql/$(date +%Y-%m-%d-%H.%M.%S).sql.bz2

Extract for all file types

This script will detect the file format of an archive and run the appropriate command to extract the files.

#!/bin/bash

if [ -f $1 ] ; then
  case $1 in
    *.tar.bz2)   tar xvjf $1    ;;
    *.tar.gz)    tar xvzf $1    ;;
    *.tar.xz)    tar Jxvf $1    ;;
    *.bz2)       bunzip2 $1     ;;
    *.rar)       rar x $1       ;;
    *.gz)        gunzip $1      ;;
    *.tar)       tar xvf $1     ;;
    *.tbz2)      tar xvjf $1    ;;
    *.tgz)       tar xvzf $1    ;;
    *.zip)       unzip -d `echo $1 | sed 's/\(.*\)\.zip/\1/'` $1;;
    *.Z)         uncompress $1  ;;
    *.7z)        7z x $1        ;;
    *)           echo "don't know how to extract '$1'" ;;
  esac
else
  echo "'$1' is not a valid file!"
fi

Go Up Directory Tree

This little script is useful for directory navigation. Say you are in a deep directory, for example, /media/megadrive/wwwroot/public_html/lonewolfonline/wp-content/themes/lonewolf/css and you wanted to go back to the root of public_html you would either have to cd ../../../.. or you can use this to go up 4 (if you name the script up).

#!/bin/bash

LIMIT=$1
P=$PWD
for ((i=1; i <= LIMIT; i++))
do
    P=$P/..
done
cd $P

Bash Script to Remove Empty Directories

This bash script will scan and remove empty directories.

#!/bin/bash

[ $# -lt 1 ] && set -- .

find "$@" -type d -depth -print |
    while read dir
    do
	[ `ls "$dir" | wc -l` -lt 1 ] || continue
	echo >&2 "$0: removing empty directory: $dir"
	rmdir "$dir" || exit $?
    done
exit 0
Tutorial Series

This post is part of the series Introduction to Linux. Use the links below to advance to the next tutorial in the couse, or go back and see the previous in the tutorial series.

Leave a Reply

Fields marked with * are mandatory.

We respect your privacy, and will not make your email public. Hashed email address may be checked against Gravatar service to retrieve avatars. This site uses Akismet to reduce spam. Learn how your comment data is processed.