- Home
- Learn Linux
- Learn Electronics
- Raspberry Pi
- Programming
- Projects
- LPI certification
- News & Reviews
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.
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.
#!/bin/bash
# Script to determine the 10 largest files in a specific directory
echo "The 10 largest files in directory" `pwd` "are:" >largefiles
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.
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.
#!/usr/bash
# Script to determine the 10 largest files in a specific directory
tempdir=`pwd`
cd $1
echo "the 10 largest files in directory" `pwd` "are:" >largefiles
ls -l | cut -c 32-41,55- | sort -nr | head >> largefiles
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
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.
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
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.
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.
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.
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
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
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.
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.
Linux Basic Shell Reference Guide
Linux Commands Basic Reference Guide
Linux Useful Command Reference Guide
The Linux Documentation Project – BASH Programming Introduction How-To