As you ve seen in this chapter, the shell has extensive capabilities when it comes to providing tools for finding your way around the operating system and getting your job done. But the true power of the shell is in its capacity as a scripting language.
To capture this, we use shell scripts . Essentially , a shell script is a sequence of commands and operators listed one after another, stored in a file, and executed as a single entity.
Shell scripting in Bash is a topic that deserves a book by itself. Our objective in this short section is simply to touch upon the salient features of scripting using Bash.
Bash shell script files start with the command interpreter, in this case bash itself:
Like most other programming languages, Bash scripting requires variables to store its data in during the course of execution. Shell scripts variables are essentially the same as regular environment variables. In fact, they are set and retrieved the same way as environment variables. Certain variables have special meanings:
$n indicates the n th argument to the script. Therefore, $1 would indicate the first argument to the script.
$0 indicates the name of the script itself.
$* prints the complete command line.
Try out a program that prints the values of special variables $n and $* :
Step 1: Creating the script
#!/bin/sh echo "Script name:#!/bin/sh echo "Script name: $0" echo "First argument: $1" echo "Second argument: $2" echo "All arguments : $*"" echo "First argument: " echo "Second argument: " echo "All arguments : $*"
The echo command (in this shell script) has the effect of interpreting and writing its arguments to the standard output.
Step 2: Running the script
You need to save this in a file called testcmd.sh :
$ chmod +x testcmd.sh $ ./testcmd.sh foo bar Script name: ./testcmd.sh First argument: foo Second argument: bar All arguments : foo bar
You run the command testcmd.sh as ./testcmd.sh because this indicates the full path of the shell script; in other words, you indicate that the testcmd.sh script residing in the current directory needs to be executed. Alternatively, you could add the current working directory to your PATH :
$ export PATH=$PATH:.
Finally, how do you specify the execution path of your code based on conditions? This is more complex than the ideas we ve looked at so far, but with that complexity comes a great deal of added flexibility. You can use conditional constructs to create extremely flexible scripts that automate many common tasks on your system.
We will begin by looking at the if then .. else .. fi conditional construct used for testing and branching. This command is useful when you need to execute a certain set of statements (commands) if a particular condition is met and a certain other set of commands if the condition is not satisfied.
You could type the following example into a file using your favorite editor and save it as a shell script, say testif.sh :
#!/bin/sh x=10 y=5 if [ "$x" -eq "$y" ] then echo x and y are equal else echo x and y are not equal fi
Then issue the following command:
$ chmod +x testif.sh; ./testif.sh
The chmod command sets execution permissions for the shell script; in other words, it makes the script executable. Chapter 5 contains detailed information on setting various permissions for files. The ./testif.sh command executes the script. You see the following output:
x and y are not equal
It is not necessary to type a shell script into a file. You can type it in at the command line itself:
$ x=10; y=5 $ if [ "$x" -eq "$y" ] > then > echo x and y are equal > else > echo x and y are not equal > fi x and y are not equal $
Note that the shell prompt changes into a > sign because the shell expects more input.
The if then ... else ... fi statement has the following syntax:
if expression then statement 1 statement 2 ... statement n else statement 1' statement 2' ... statement n' fi
If the value of the expression turns out to be true, the statements from statement 1 to statement n are executed. If it evaluates to false, the statements from statement 1 to statement n are executed. The expression can be formed using operators, in this case the “eq operator. The “eq operator tests for equality of numbers. It evaluates to true if two numbers are equal and false if they are not.
A shorter form of this construct is the if then .. fi construct that follows :
if expression then statement 1 statement 2 ... statement n fi
This construct is useful when you need to execute certain statements only if a certain condition is met. Following is a sample script that uses the if then .. fi form:
#!/bin/sh x=10 y=5 if [ "$x" -eq "$y" ] then echo "The two numbers are equal" fi
Note that in both cases the statements are indented to make the code more readable and this is not a requirement.
The previous examples used operators such as “e q to evaluate conditions. The following table lists commonly used operators and their functions.
Tests to See If . . .
"$x" “eq 3
Both integer operands are equal.
"$x" “neq 3
Both integer operands are not equal.
"$str" = "some string"
Both string operands are the same.
"$str" != "some string"
Both string operands are not the same.
The operand is of non-zero length.
The operand is of zero length.
The specified directory exists.
The file specified exists.
$x “lt $y
First integer operand is lesser than the second integer operand.
$x “le $y
First integer operand is lesser than or equal to the second integer operand.
$x “gt $y
First integer operand is greater than the second integer operand.
"$x" “ge "$y"
First integer operand is greater than or equal to the second integer operand.
This section looks at looping constructs that allow you to conditionally execute a set of statements repeatedly.
The for loop is essentially a simple looping construct that allows you to specify a set of statements that need to be executed a certain number of times:
#!/bin/sh for fil in `ls *.txt` do cat $fil >> complete.txt done
The preceding script concatenates all the text files in the current directory into a text file, that is, complete.txt .
#!/bin/sh for number in 1 2 3 4 5 do echo $ done
This script prints out the numbers from 1 to 5 producing the following output:
1 2 3 4 5
The syntax of the for construct is as follows:
for variable in word do statement 1 statement 2 ... statement n done
Here, word is a set of items that gets assigned to the variable one at a time for each iteration of the loop. The loop therefore executes as many times as there are items in the word.
The while looping construct tests a logical condition for continuing the looping:
#!/bin/sh x=10 y=5 while [ "$x" -ge "$y" ] do echo $y y=`expr $y + 1` done
The preceding script displays the following output:
5 6 10
The syntax of the while construct is as follows:
while expression do statement 1 statement 2 . . statement n done
The while loop continues as long as the expression evaluates to true.
You ve had just a taste of the functionality that your Bash shell has to offer. Many good books exist on the subject that you can consult if you wish to learn more about its more complex functionality.