to the string Example
, when I echo the value of THIS
it appears as Example
. However, because THAT
was not set, it appears as Not Set
.
NOTE
For the rest of this section, I show how variables and commands may appear in a shell script. To try out any of those examples, however, you can simply type them into a shell, as shown in the previous example.
In the following example, MYFILENAME
is set to /home/digby/myfile.txt
. Next, the FILE
variable is set to myfile.txt
and DIR
is set to /home/digby
. In the NAME
variable, the filename is cut down simply to myfile
; then, in the EXTENSION
variable, the file extension is set to txt
. (To try these out, you can type them at a shell prompt as in the previous example and echo the value of each variable to see how it is set.) Type the code on the left. The material on the right side describes the action.
MYFILENAME=/home/digby/myfile.txt: Sets the value of MYFILENAME
FILE=${MYFILENAME##*/}: FILE becomes myfile.txt
DIR=${MYFILENAME%/*}: DIR becomes /home/digby
NAME=${FILE%.*}: NAME becomes myfile
EXTENSION=${FILE##*.}: EXTENSION becomes txt
Performing arithmetic in shell scripts
Bash uses untyped variables, meaning it normally treats variables as strings of text, but you can change them on the fly if you want it to.
Bash uses untyped variables, meaning that you are not required to specify whether a variable is text or numbers. It normally treats variables as strings of text, so unless you tell it otherwise with declare
, your variables are just a bunch of letters to bash. However, when you start trying to do arithmetic with them, bash converts them to integers if it can. This makes it possible to do some fairly complex arithmetic in bash.
Integer arithmetic can be performed using the built-in let
command or through the external expr
or bc
commands. After setting the variable BIGNUM
value to 1024
, the three commands that follow would all store the value 64
in the RESULT
variable. The bc
command is a calculator application that is available in most Linux distributions. The last command gets a random number between 0 and 10 and echoes the results back to you.
BIGNUM=1024 let RESULT=$BIGNUM/16 RESULT=`expr $BIGNUM / 16` RESULT=`echo "$BIGNUM / 16" | bc` let foo=$RANDOM; echo $foo
Another way to grow a variable incrementally is to use $(())
notation with ++I
added to increment the value of I
. Try typing the following:
$ I=0 $ echo "The value of I after increment is $((++I))" The value of I after increment is 1 $ echo "The value of I before and after increment is $((I++)) and $I" The value of I before and after increment is 1 and 2
Repeat either of those commands to continue to increment the value of $I
.
NOTE
Although most elements of shell scripts are relatively freeform (where white space, such as spaces or tabs, is insignificant), both let
and expr
are particular about spacing. The let
command insists on no spaces between each operand and the mathematical operator, whereas the syntax of the expr
command requires white space between each operand and its operator. In contrast to those, bc
isn't picky about spaces, but it can be trickier to use because it does floating-point arithmetic.
To see a complete list of the kinds of arithmetic that you can perform using the let
command, type help let at the bash prompt.
Using programming constructs in shell scripts
One of the features that makes shell scripts so powerful is that their implementation of looping and conditional execution constructs is similar to those found in more complex scripting and programming languages. You can use several different types of loops, depending on your needs.
The ″if…then″ statements
The most commonly used programming construct is conditional execution, or the if
statement. It is used to perform actions only under certain conditions. There are several variations of if
statements for testing various types of conditions.
The first if…then
example tests if VARIABLE
is set to the number 1
. If it is, then the echo
command is used to say that it is set to 1
. The fi
statement then indicates that the if
statement is complete, and processing can continue.
VARIABLE=1 if [ $VARIABLE -eq 1 ] ; then echo "The variable is 1" fi
Instead of using -eq
, you can use the equal sign (=
), as shown in the following example. The =
works best for comparing string values, while -eq
is often better for comparing numbers. Using the else
statement, different words can be echoed if the criterion of the if
statement isn't met ($STRING = ″Friday″
). Keep in mind that it's good practice to put strings in double quotes.
STRING="Friday" if [ $STRING = "Friday" ] ; then echo "WhooHoo. Friday." else echo "Will Friday ever get here?" fi
You can also reverse tests with an exclamation mark (!
). In the following example, if STRING
is not Monday
, then ″At least it's not Monday″
is echoed.
STRING="FRIDAY" if [ "$STRING" != "Monday" ] ; then echo "At least it's not Monday" fi
In the following example, elif
(which stands for “else if”) is used to test for an additional condition (for example, whether filename
is a file or a directory).
filename="$HOME" if [ -f "$filename" ] ; then echo "$filename is a regular file" elif [ -d "$filename" ] ; then echo "$filename is a directory" else echo "I have no idea what $filename is" fi
As you can see from the preceding examples, the condition you are testing is placed between square brackets [ ]
. When a test expression is evaluated, it returns either a value of 0, meaning that it is true, or a 1, meaning that it is false. Notice that the echo
lines are indented. The indentation is optional and done only to make the script more readable.
Table 7.1 lists the conditions that are testable and is quite a handy reference. (If you're in a hurry, you can type help test on the command line to get the same information.)
TABLE 7.1 Operators for Test Expressions
Operator | What Is Being Tested? |
-a file
|
Does the file exist? (same as -e)
|
-b file
|
Is the file a block special device? |
-c file
|
Is the file character special (for example, a character device)? Used to identify serial lines and terminal devices. |
-d file
|