BASH Scripting

BASH (Bourne-Again Shell)– Scripting 101 –

BASH scripting is a very useful tool for automating tasks on a Unix system, it can be used for anything from resetting passwords, to starting applications, to simply storing your favourite grep function for kernel logs.
The entire idea about this tutorial and any others to follow it, is to reduce the amount of time you spend on any given task, reduce the number of keystrokes you have to hit, and reduce the incidences of RSI caused by working on Unix systems.

All bash scripts should end with a “.sh” file extension to show that they are scripts.
They MUST be given execute rights on the system to do so run the below.

> chmod 750 script.sh

To run a bash script we simply go

> ./script.sh one two three

This will run the script “script.sh” that exists in the “.” directory (current working directory) and pass it the values “one”, “two”, “three”

So let’s look at a sample bash script.

#!/bin/bash
# Dumb Backup Script
# Author - Benjamin Way
# Email - benjamin.way@datacom.co.nz
for file in "$@"
do
  if [ -f ${file} ]
  then
    filenew="${file}_$(date -d @$(stat -c%Y ${file}) +%F)"
    cp ${file} ${filenew}
    echo "${file} - copied as ${filenew}"
  else
    echo "${file} - does not exist"
  fi
done
exit 0

This script takes a list of files, and makes copies of them, appending the last modified date to the end.

So let’s go over it bit by bit.

#!/bin/bash

This tells the system that this is a Bash Script. It is required for EVEY bash script you write, and MUST be the first line.

# Dumb Backup Script
# Author - Benjamin Way
# Email - benjamin.way@datacom.co.nz

These are Comments, you should ALWAYS provide an email address for any code you are proud of. and NEVER provide it for code that people will complain about. Thats my standpoint anyway.

for file in "$@"
do
# STUFF
done

This is a for loop. The “$@” means that it will do stuff for every variable passed into the script. The file mentioned here is the name of the variable we will store the current itterations value in.

backup.sh one two three
would result in an itteration for each of “one” “two” and “three” with $file storing the value we are working on for that itteration.

“do” means the start of the actions for the loop. “done” is the end of the actions for the loop.

if [ -f ${file} ]
then
# STUFF
else
# MORE STUFF
fi

This is an If statement in Bash. If the result of [ -f ${file} ] is true, then it will execute the statements between “then” and “else”, if false it will execute the statements betweek “else” and “fi”
[ -f ${file} ] will check if the file exists using the test command.
See: http://man7.org/linux/man-pages/man1/test.1.html

filenew="${file}_$(date -d @$(stat -c%Y ${file}) +%F)"

This line means to store the value after the equals in the variable $filenew. When we store variables we don’t use the “$”, when we call them we need to use the “$”.
There MUST be no space around the “=”, or bash will not store the file.
The Quotes mean that non-variables will be interpreted as part of a string. And variables will have their value placed into the string.

${VARIABLE}

This is called protecting the variable. It means that you can put it directly beside text, and it will cause fewer issues. Get in the habit of ALWAYS protecting your variables.

$( #SOMETHING )

This is a code execution, it will execute the code within itself, and then return it’s contents. You use it to store the output of programs as variables, or to use the output in a string.

$(stat -c%Y ${file})

This will run the stat command on the file we are looking at, and report the timestampof it’s last modification.
The output will be fed back into the next part of the statment…

$(date -d @#### +%F)

Where the #### is the output of the last statement.
This will simply execute the date command, using the provided timestamp instead of the current time, and format it as “%F”
” %F full date; same as %Y-%m-%d” -From the Man page for date.

filenew="${file}_####"

This will therefore store a string that consists of the original filename, an underscrawl, then the date of the last modification in the format “yyyy-mm-dd”

cp ${file} ${filenew}
echo "${file} - copied as ${filenew}"

The first part will run the copy command and copy $file to $filenew
The second part will simply tell us that this has happened.

echo "${file} - does not exist"

Likewise this will tell us that the file does not exist. (Or was not a normal file)

exit 0

Simply quits the script, and returns 0 to the system.
This is interpreted as a successful exit.
To exit with a failure, you would put a non-zero value instead of zero.

This is a very basic script, and does not cover any math nor many of the useful sections of BASH scripts.
But it should give you an idea of how a BASH script works.