A shell script is a file containing a series of commands. The process of scripting is the writing of those commands in the file. The shell can read this file and act on the commands as if they were typed at the keyboard.
Because there are many commands available to use we can realise the real power of computing and the reduction of repetitive tasks by automating processes.
Think of shell scripts as program commands which are chained together and which the system can execute as a scripted event. They make use of functions such as command substitution where we can invoke a command, like date, and use it’s output as part of a file-naming scheme. Scripts are programs in their own right which use programming functions such as loops, variables and if/then/else statements. The beauty of scripting is that we don’t have to learn another programming language to script effectively, we simply use the commands we use at the command line.
To successfully write a script to do something we have to do three things;
Write a script (a file with a ‘.sh’ extension) that uses common commands.
Set the permissions on the file so that it can be executed
Place the file somewhere that the shell can locate it when it’s invoked
Writing our Script
The script itself is just a text file. The only thing fancy about it is that it contains commands and we’re going to make it executable.
We can start with a simple example that demonstrates echoing a simple message to the screen.
Starting in our home directory (/home/pi) we can use the nano editor to create our script by running the following command;
This will open the nano editor and we can type in something like the following;
The first line of the script is important because it provides information to the shell about what program should be used to interpret and run the script. The line starts with a ‘shebang’ (#!) and then the path to the program (in this case /bin/bash).
The second line is a comment that we would place in a script to tell ourselves or others that open the file what is going on. Anything that appears after a # mark (except for on the first line with the ‘shebang’) will be ignored by the script and is entered to make notes for the reader.
The last line is the command we will run. In this case it only one command, but it could also be any number. The command in this case is a very simple echo command to print the words ‘Hello World!’ to the screen.
Once finished we can close and save the file (CTRL-x to close and say ‘y’ to save);
That’s our script written.
Make the script executable
If we list the properties of our file sayhello.sh with ls as follows;
… we will see the details of the file something like this;
Linux permissions specify what the owning user can do, what a member of the owning group can do and what other users can do with the file. For any given user, we need three bits to specify access permissions: the first to denote read (r) access, the second to denote (w) access and the third to denote execute (x) access.
We also have three levels of ownership: ‘user’, ‘group’ and ‘others’ so we need a triplet (three sets of three) for each, resulting in nine bits.
The following diagram shows how this grouping of permissions can be represented on a Linux system where the user, group and others had full read, write and execute permissions;
Linux permissions as rwx
The permissions of our sayhello.sh file tell us that the user can read and write the file, members of the group and anyone else can read the file. What we need to do is to make it executable using the chmod command
Here everyone has execute permissions and the ‘pi’ user and the ‘pi’ group have read and write permissions.
Place the script somewhere that the shell can find it
Currently we’re working in the ‘pi’ home directory where we’ve saved our file. This should be the easiest example of making the script accessible and as such we should be able to simply run the command directly from the command line as follows;
The output from the command should look something like this;
The ./ notation in front of the script designates the path to the file being our current directory. We could have also provided the full path as follows;
(Since /home/pi/ is the directory that the file is currently in.)
So that works, but in the perfect world we wouldn’t need to designate a path to the script in order to execute it. We can make that happen by placing the script in one of the directories in the users ‘PATH’.
PATH is an environmental variable that tells the shell which directories to search for executable files. It should not be confused with the term ‘path’ which refers to a file’s or directory’s address in a files system
A user’s PATH consists of a series of colon-separated absolute paths. When we type in a command at the command line that is not distributed with the operating system or which does not include its absolute path and then the shell searches through the directories in PATH, which constitute the our search path, until it finds an executable file with that name.
We can check what the paths available are by echo-ing the PATH variable to the screen like so;
This will then report PATH to the screen something like the following
We can therefore add our script to any of those directories and it will work like a normal command. However, this will make it available to all users on the system and if we want to only make it available to ourselves as the current user we will need to add a new path to PATH.
The good news is that this is simple to do and in Debian Jessie all we need to do is to create a directory in our home directory (if we are logged in as the ‘pi’ user, that would be /home/pi) called bin. We can place any script that we want to be available to the ‘pi’ user in there and they will have access to it. The reason they will have access is that while it doesn’t appear in PATH at the moment, when we add the bin directory to our home directory, there is a script called .profile which gets checked whenever we start our bash shell. If .profile sees that we have a bin directory in our home directory it adds it to our PATH.
So if we add the directory using mkdir as follows;
… we will be set up with a new path in PATH the next time we start our shell.
Let’s not forget that we should move our file into our new directory with mv as follows;
If we open a new terminal and log on as our user (it’s ‘pi’ in the example) we can how go anywhere (cd) in the directory structure and simply run the command;
… and get the response;
That’s the completion of our simple first example. More advanced work with loops, variables and if/then/else statements will have to be an exercise for the reader. Hopefully that’s ‘Just Enough’ to get you started.
The post above (and heaps of other stuff) is in the book 'Just Enough Linux' that can be downloaded for free (or donate if you really want to :-)).