Bash Script - Example

Bash Scripts - An example

I thought I might share with you, those that are interested that is, how you might write your own useful "bash script". Well just what is a "Bash" script? to answer that you first need to know where the word Bash comes from, it is a *nix term given to one of the many various shell(s) in use the likes of Unix, Linux and yes Mac's, of which these are only accessible from the terminal. A terminal console on it's own does very little it needs to run using a shell of some sought, these shells and by now there are a few of them for *nix family essentially do different jobs, but the one you are most likely to use is the bash shell as it is perhaps the most popular.

Shells

Brian Fox began coding Bash in January 1988 after Richard Stallman became dissatisfied with the lack of progress being made by a prior developer. Stallman and his Free Software Foundation (FSF) considered a free shell that could run existing sh scripts so strategic to a completely free system built from BSD and GNU code that this was one of the few projects they funded themselves, with Fox undertaking the work as an employee of FSF. Fox released Bash as a beta, version, on June 1989.

All operating systems use shells, and if you are interested in the nature, history and functions within a shell you might want to look at this reference table Shell table

How to work with the Bash Shell - Bourne again shell

First of all how do you know what shell you are running.

#> env

Type "env" on the command line of your command terminal and your shell will be revealed to you along with a load of other stuff more perhaps than displayed here.

ORBIT_SOCKETDIR=/tmp/orbit-delboy
SSH_AGENT_PID=1771
TERM=xterm
SHELL=/bin/bash
XDG_SESSION_COOKIE=7ecd9b46cf8b544a3c3423f900000004-1295557623.833052-85324362
WINDOWID=65011716
GNOME_KEYRING_CONTROL=/tmp/keyring-ODqOyZ
GTK_MODULES=canberra-gtk-module
USER=delboy
LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;
.................
SSH_AUTH_SOCK=/tmp/keyring-ODqOyZ/ssh
DEFAULTS_PATH=/usr/share/gconf/gnome.default.path
USERNAME=delboy
SESSION_MANAGER=local/Studio:@/tmp/.ICE-unix/1742,unix/Studio:/tmp/.ICE-unix/1742
XDG_CONFIG_DIRS=/etc/xdg/xdg-gnome:/usr/share/ubuntustudio-menu/:/etc/xdg/
DESKTOP_SESSION=gnome
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games
PWD=/home/delboy/Music
GDM_KEYBOARD_LAYOUT=gb
GNOME_KEYRING_PID=1723
LANG=en_GB.utf8
MANDATORY_PATH=/usr/share/gconf/gnome.mandatory.path
GDM_LANG=en_GB.utf8
GDMSESSION=gnome
SHLVL=3
HOME=/home/delboy
GNOME_DESKTOP_SESSION_ID=this-is-deprecated
LOGNAME=delboy
DBUS_SESSION_BUS_ADDRESS=unix:abstract=/tmp/dbus-af1mXUGedg,guid=09173ee54358a9297adbedbc0000001c
XDG_DATA_DIRS=/usr/share/gnome:/usr/local/share/:/usr/share/
LESSOPEN=| /usr/bin/lesspipe %s
WINDOWPATH=7
DISPLAY=:0.0
LESSCLOSE=/usr/bin/lesspipe %s %s
COLORTERM=gnome-terminal
XAUTHORITY=/var/run/gdm/auth-for-delboy-EkjAzr/database
_=/usr/bin/env

Generally you do not need to know what shell your running but at least you now know how. A shell script or a Bash shell script is a pre programmed response of commands. Let me give you an example:-

If you have ever tried to play Music from the command line it can sometimes prove to be very difficult this is because humans and PC's (Machines) deal with Capitals and especially spaces differently, as humans we ignore spaces or rather realise that such notation helps us to read and interpret a series of words, a line, a sentence, a paragraph when chained together. PC Machines and especially *nix terminal interpret these series of words with Capitals and spaces as a unique identifier let me show you what I mean.

cat dog - Two words that might have meaning with reference to a script. But and here is where the Windows operating system differs to most of the rest.

cat
Cat
dog
Dog

In Unix all the above are considered unique, so whilst cat & Cat are the same word they are not spelled the same this can sometimes be beneficial as similar files can be called the same just with slightly different notation, this maximizes on the files that could be stored. Single words in any *nix or Windows for that matter would not cause that much of a problem until that is we use a string of words, to describe a file perhaps and make it easier to locate.

Lets consider this as a filename.

The cat belongs with me

Ok the above filename is descriptive but with nothing on the end by way of a suffix it is difficult to know what type of file text, doc, mp3 and so on, this is that's our first problem second problem and less obvious are the spaces that separate each of the words, third is use of capitals within the string of letters this on its own is little or no problem. But because we can, in the same directory use almost the same string of words, a single letter change is enough to say lower case, the two strings can exist in the same directory. Windows on the other hand ignores capital letters and does not care about case for any of the words that might use it so two such strings cannot exist in the same directory.

*nix doe not care if you use a suffix on the end of a filename or not it relies on embedded information to determine file type and as a result it is less reliant on suffix extensions than Windows. Spaces are more of a problem however especially for *nix, the problem presents itself at the command line of *nix systems spaces are denoted as special characters and must be preceded by a backwards slash before the space between each and every word.

Lets consider this line again:-

The cat belongs with me

In *nix we would need to address the line, especially if we wanted to copy or move the file from the command line in a terminal thus:-

The\ cat\ belongs\ with\ me

The longer the string the greater the problem and with an abundance of similar named files in same directory the selection of a single file becomes very difficult and unmanageable.

To make things easier I hope, it would help if we stick to a few rules when creating files, however sometimes this is somewhat beyond that of our control. The command script below will change all upper case letters to lower case.

Open a terminal and change directory "cd" to a directory in your home that perhaps contains a mixture of upper and lower case characters and run the command below without any alteration the upper case letters will be converted to lower case:-

#> find . -depth -exec rename 's/(.*)\/([^\/]*)/$1\/\L$2/' {} \;

I can't begin to tell you how this command works other than the fact it uses regular expressions, but it does, however the command below does exactly the same thing, if your nervous using the above command. I must admit it does look creepy.

#> for i in *; do mv "$i" "$(echo $i|tr A-Z a-z)"; done

This will organise all the files in the current directory to that of lower case and corrects the third problem that was mentioned above that of mixed case files, next we want to run another command that alters the spaces for underscores:-

#> for i in *; do mv "$i" `echo $i | tr ' ' '_'`; done

We actually want to do this as (at least I feel the use of the back slash proceeding a space is inappropriate).

Creating a Bash Script

As you can see we needed to use two set of commands to perform the function of changing the character set to the uniform lower case the second command converted all spaces to underscores, strange as it may seem changing from spaces to underscores makes locating a filename from the command line very much easier. If of course you have only one long filename with spaces the TAB key will go straight to the file but when you have many and they all begin with the same set of characters that's when the trouble starts.

Use an editor like vim, gedit, nano or anyone you are familiar with open a blank or new named file whichever you feel comfortable with your very first line should and must look like this:-

#!/usr/bin/bash

This tells the computer the command interpreter to use and where to find it vital is #! pronounced "hash" "pling" immediately before the full location of the bash interpreter.

You can leave one new line and begin to write your new program you are advised when writing any script to add remarks to help identify what the script does when it was written by whom, it is extremely good advice and considered good coding practice.

Here is the snippet of code that should be in your shell script.

#!/usr/bin/bash # Author - Derek Shaw
# Date - 23rd January 2011
# Description - A program that when run in a directory will seek and alter to lower case filename created using a
# mixture of upper and lower case characters it will also convert spaces to underscores.
find . -depth -exec rename 's/(.*)\/([^\/]*)/$1\/\L$2/' {} \;
for i in *;
do mv "$i" `echo $i | tr ' ' '_'`;
done

You can copy the above script I hold no rights to it and use it freely copy the section marked with a gold background and paste this into your own bash script on your own computer add to it modify it as you wish of course if you can improve it's functions please send a copy to SoSLUG so all can benefit from your learning. Or better still register and compose a wiki page of your own.

After you have copied this file to a text editor you need to save it when doing so please consider using the format filename.sh where filename is a short description of the function of the script, the sh extension is not compulsory but will help the file stand out when locating it to use the script.

You can then if you wish make the script executable so it can be called at anytime without preceding the filename with another command.

First option call the filename using another command in this case sh (shell command)

#> sh ./<Path>/filname.sh

Second option is to convert filename to an executable, conversion would be a permanent change and would only need to be applied once, however you will still need to define the path from which to call the script. Please note "./" denotes the current directory the command will only run if this or the full path is specified.

#> chmod +x /home/user/<Path>/filename.sh #> ./<Path>/filename.sh