This post is going to be a short course in bash scripting. This is aimed at Linux users. I am basing this course off the Linux Academy course on udemy.com.
I have divided this up as follows:
- What is a Bash script?
- Basic script structure
- Logic and Testing
- Loops, Functions and Case statements
- User input
What is a Bash script?
As we delve into this answer, I am going to assume two things:
- You understand some basic Linux commands and are familiar with the command line interface
- You have a basic understanding of programming languages, what they look like and how they are structured
So what is a Bash script?
A script is a repeatable sequence of commands, and what I mean by that is that a script is a file, which contains a list of commands that are executed in a predictable and known order. A program file if you like.
We write scripts for several reasons
- to automate tasks
- to save time
- to decrease repetition
Lets say we have a task that we perform daily, and that task is always the same set of commands; we can write a script to run those commands, and in doing so, we automate that daily task.
We could add that task to the cron tab, having it run automatically when required (daily in this case). It is these capabilities that make shell scripting so very powerful.
But, what about the ‘Bash” bit?
Bash ( Bourne Again SHell) is a Linux shell, which is a command line environment (or interpreter) that a Linux user can use to send instructions to the Linux Kernel. There are a number of shells in common usage (sh, bash, csh, zsh etc) but bash is probably the most well known and used. The shell (bash in this case) is what takes your instructions and passes them to the kernel for execution.
Basic Script Structure
In its simplest form, a script is a text file with a list of instructions. In order to make a text file with a list of instructions into a shell script, we have to do a few things:
1. Where is bash?
Bash is essentially a program that runs within Linux, and we can find that program by typing: which bash. In most cases we get the answer /bin/bash. Because it is a program, paths become important if we wish to run our scripts.
2. Tell Bash that this is a shell script
We also need to tell bash that we have a script and not just a list of commands. We do this by putting a marker at the beginning of the file. This is the #!/bin/bash (otherwise known as a shebang) with the path to the bash shell, so that Linux knows how to process this file.
3. Give the script permission to execute
When I create a script, by default, it is saved with our basic permission set, which does not include user execute permission – because most of the time, user files are not executable. In this case we have to change the permission to allow user execution.
So lets make a script:
Remember the old days of BASIC (yeah I am that old) – lets do this:
$ echo hello world
Just like the old BASIC program:
10 PRINT “Hello World”
20 GOTO 10
and who didn’t love doing that …
Now lets put it in a script:
$ nano myscript
$ cat myscript
echo Hello World
I like to use nano because I can never remember the commands for vi. I am lazy and should learn the vi commands, but I just don’t seem to be able to bring myself to do it.
Paths and the Environment
The chances are that you are using a user friendly flavor of Linux, like Ubuntu or similar and you created this file in your user directory.
Chances are that when you ran the file, you got something like this:
No command 'myscript' found, did you mean:
Command 'pyscript' from package 'python-pyscript' (universe)
myscript: command not found
The problem here is the PATH environment variable. Path is what tells Linux where the programs are that you want to run. if you echo $PATH you will see all the paths that Linux looks in for programs, and your user directory is not one of them, so when you type your command (or in this case script filename), Linux can’t find it.
Also these new Linux versions tend not to install with a local /bin directory but where that directory is installed, the profile script that runs during login will have detected the bin directory and placed it in the PATH environment. With Ubuntu, if you create a /home/username/bin directory, logout and then log back in again, and put your script in there, it will run. Here is my path environment, and I have high lighted the local bin directory.
$ echo $PATH
No now we need to set the permissions so that the script can run.
-rw-rw-r-- 1 tony tony 30 Jan 29 10:42 myscript
chmod u+x myscript
-rwxrw-r-- 1 tony tony 30 Jan 29 10:42 myscript
See the eXectable bit set in the permissions?
And there it is! Our very first script.
Just another quick note – if you run this in another folder, you can run it this way: sh myscript. This negates the requirement for the PATH environment to be set, but it really isn’t that useful for continuous use. Or you can run it like this ./myscript will also work, or lastly, make a direct link to the file as in /home/user/script or what ever your path maybe.
But our script, as fun as it was to play with, is not a very useful script. Lets make something more useful. This uses the tar function to create a zipped backup file of my user directory. Note also that I can comment in the script using the # symbol.
~/bin$ nano backup
~/bin$ cat backup
# This is a backup script
tar -cvzf backup.tar.gz /home/tony
# create verbose zip and file options.
cp $HOME/backup.tar.gz /home/tony/bin
# copy to the local bin folder
echo backup complete
bash: /home/tony/bin/backup: Permission denied
So what happened? Well we need to change the permissions; so lets chmod u+x backup and try again.
I’m not going to print the output (it is after all verbose) but it works!
~/bin$ ls -al
drwxrwxr-x 2 tony tony 4096 Jan 29 13:39 .
drwxr-xr-x 40 tony users 4096 Jan 29 11:30 ..
-rwxrw-r-- 1 tony tony 207 Jan 29 13:33 backup
-rw-rw-r-- 1 tony tony 5401362432 Jan 29 13:44 backup.tar.gz
Now lets take a look at some more detail in part 2.