Third party cookies may be stored when visiting this site. Please see the cookie information.

PenguinTutor YouTube Channel

Basic shell programming reference guide

The Linux shell is more than just a way of running commands that users type in. It can be used as a programming environment for everything from basic scripts similar to DOS batch (.bat) files, to complicated programs. The real name for these are shell scripts as they are dependent upon the shell they are running in, however for brevity I will just refer to them as scripts.

Here are some of the basic instructions that can be used to alter how a script might run. I'm assuming that you already have some knowledge of running commands, and using pipes and redirection. If these are new terms then you may like to take a look at: Linux Basic Shell Reference Guide, Linux Commands Basic Reference Guide, and Linux Useful Command Reference Guide.

First script

Here’s a first script file. This can be entered into a text file and then set to executable using chmod so that it can be run.

  1. #!/bin/bash
  2. # Script to determine the 10 largest files in a specific directory
  3. echo "The 10 largest files in directory" `pwd` "are:" >largefiles 
  4. ls -l | cut -c 32-41,55- | sort -nr | head >> largefiles

This file will output to the file $HOME/largefiles a title followed by details of the 10 largest files in the current directory.

Normally in a script a comment is denoted by the hash character as per line 2. The first line is a special case when it denoted by a hash followed by an exclamation mark '#!'. This is known as a hashbang or shebang and indicates that the rest of the line is an interpreter directive. In this case it identifies this as a bash script and so will ask bash to interpret the file and run as appropriate.

Line 3 uses the echo command to add some text into the largefiles file. The back-ticks around pwd cause that to be executed as a command.

Line 4 uses the cut command to extract the relevant parts from the ls command, sorts it into numerical order and then using the head command just return the first 10 entries. These are then appended to the largefiles file.

Script using command line variables

The script can be made more useful by allowing it to accept the directory name on the command line. This is done by using the variables $1, $2 etc. to represent argument1, argument2 etc.

  1. #!/usr/bash 
  2. # Script to determine the 10 largest files in a specific directory
  3. tempdir=`pwd` 
  4. cd $1 
  5. echo "the 10 largest files in directory" `pwd` "are:" >largefiles
  6. ls -l | cut -c 32-41,55- | sort -nr | head >> largefiles
  7. cd $tempdir 

In addition to the use of the $1 argument used on line 4. This script also uses a local variable on line 3 and 7.

This script will now.

Store the current directory

Change to the directory given as the first argument (if no directory is given will change to the default home directory)

Put the Title in the file

List the 10 largest files in the current directory

Return to the stored directory

Shifting arguments (shift)

The shift command allows you to shift all the arguments one to the left.

The value in $2 is put into $1
The value in $3 is put into $2
etc.

This is particularly useful when programming for the bourne shell as it allows more than 9 arguments to be passed, whereas the bash shell will accept any number of arguments directly.

Testing for a condition

To make the scripts a bit more useful you can only run certain parts of the code under certain circumstances. This is done using an "if" construct.

In the following example the code will only be run if the condition is met, which in this case is that $VARIABLE is equal to 10.

if [  $VARIABLE1 =10 ] then

        echo The condition was true

fi 

Note the end of the code is marked by the fi statement, which is "if" backwards.

It may be that you want to run some different code depending upon whether the condition was met or not. In the following example the first part will be run if the condition is met, but the second part will be run if not.

if [  $VARIABLE1 =10 ] then

        echo The condition was true

else 

        echo The condition was false

fi 

Loops

Often you will want to run a command several times. Whilst these can be listed individually in the script it is often useful to create a loop, where the code is run multiple times.

Standard for loop

The for loop will run the code for each element passed in an array. This can be used with a command to run the script against each line of output.

for i in $( ls ) 

do 

        echo entry: $i

done 

This simple example will just print out each entry from the for loop, prefixed with the text "entry: "

The for loop will run over every entry in the array (in this case a dynamic array created from the ls command).

The value from that element in the array is stored in the variable $i.

Then the code between the do and done entries is run for each of these iterations of the for loop.

C / Java style for loop

In C or Java programming the standard for loop is typically used to run a loop for a certain number of times (often until a variable number is met), or until a condition is met. A C style for loop can be created in a shell script as follows:

for i in `seq 1 10`; 

do 

        echo $i

done

In this case the for loop will run the code with the variable $i having values from 1 to 10. This works by the seq command creating all the entries from 1 to 10.

While Loop

The while loop will run the loop as long as the condition is met. In the example below that is as long as $VARIABLE1 is less than 10.

while [  $VARIABLE1 -lt 10 ]

do 

        echo $VARIABLE1

        let VARIABLE1= VARIABLE1+1;

done 

Until Loop

The until loop is similar to the while loop, except instead of running the code when the condition is met, the until loop will run the code until the condition is met.

until [  $VARIABLE1 -gt 10 ]

do 

        echo $VARIABLE1

        let VARIABLE1= VARIABLE1+1;

done 

Script Portability

There are a number of differences between how the different shells work. This is even more important when we start writing script files. If you will only ever run the scripts yourself in the same shell this is not an issue however if others will run the script, they could run it from a different shell with unpredictable results.

To overcome this the first method is to tell the script to run under a certain shell by including the following command at the start of the file.

#!/bin/bash
for bash shell

or

#!/bin/sh
for bourne shell

You may be wondering why you would want to use the bourne shell when the bash shell provides more functionality. One reason may be for portability to a system that doesn’t have the bash shell. If you script will always be used on a system with the bash shell (which is virtually all UNIX like systems these days) then this is not an issue however some people prefer to create bourne shell scripts for maximum portability across different UNIX operating systems.

There are also a number of different script programming languages that could be used as part of this first line.

More advanced shell programming

This gives some of the basic elements of shell programming in bash. There are lots more than can be done with shell programming, but this should give an idea of what can be achieved as a starting point for future research.

Further reading

Linux Basic Shell Reference Guide
Linux Commands Basic Reference Guide
Linux Useful Command Reference Guide
The Linux Documentation Project – BASH Programming Introduction How-To

Other Raspberry Pi Projects and tutorials

Previous Guide to the Apache mod_rewrite module
Guide to the Apache mod_rewrite module
Next Introduction to regular expressions
Introduction to regular expressions