filename
(or
>>
filename
to append to an existing file).
#!/bin/bash
date
echo
# output a blank line
du –s ~
echo
# output a blank line
find ~ empty
>>
empty_report.txt # redirect output
248
◾
Linux with Operating System Concepts
Here, the choice of using the redirection operator
>>
to send the result of find to a
file allows us to accumulate this information every time we run the script, rather than
replace it. If we also redirect date to empty_report.txt, we can track the files that are
empty over time.
An alternative to performing redirection within the script is to redirect the script’s out-
put. Consider the following script: called start:
#!/bin/bash
date
echo
du –s ~
echo
find ~ empty
Rather than executing start simply as .
/start
, we could redirect the script’s output by
using
./start
>>
start_up_output.txt
What should we do with this script once it is written? While we could just try to remem-
ber to run it from time to time, we could schedule its execution. Later in the text, we look
at the scheduling commands at and crontab. A user might want to execute this script
every time they start a bash shell or log in. Recall from Chapter 2 that your .bashrc file is
executed every time you open a bash shell and your .profile file is executed every time you
log in. The user could add .
/start
into the user’s .bashrc or .profile file. Alternatively, the
user could place the contents of the script (date, echo, du –s ~, etc.) directly in the .bashrc
or .profile file.
7.2.3 Scripting Errors
There are many reasons why a script might generate an error. Unfortunately for us as pro-
grammers, the errors are only caught at run-time. That is, you will only know if an error
exists when you try to run the script. This differs from compiled programming languages
where the compiler will discover many or most of the errors that might exist in a program
when you compile the program. Here, there are no syntax errors but instead run-time
errors that might be caused by syntactic issues (such as misspelling a reserved word) or
execution issues (such as dividing by zero).
Unfortunately the error messages provided by the Bash interpreter may not be particu-
larly helpful. What you will see in response to an error is the line number(s) in which an
error arose. Multiple error messages can be generated because in most cases, if an error
occurs, the Bash interpreter continues to try to execute the script.
Let us consider a couple of errors that we might come across. The following script uses
an assignment statement and an output statement (echo). Since we have already seen these
in Chapter 2, you should have no difficulty understanding what this script is supposed to
do. Assume this script is stored in the file
error
.
Shell Scripting
◾
249
#!/bin/bash
NAME
=
Frank Zappa
echo $NAME
When run, we receive the message:
./error: line 3: Zappa: command not found
This message indicates that when Bash attempted to run echo $NAME, something went
wrong. Specifically what went wrong was that $NAME is storing two values with no quotes
around it, so retrieving the value from $NAME yields an error. We did not get an error
with the second instruction though. The solution to this error is to place “” around Frank
Zappa in the second line.
In the following case, we have a script that performs a series of operations for us. You
can see we are using wc to obtain information from the /etc/passwd, /etc/group, and /etc/
shadow files. These three files store user account information. In this case, we are just out-
putting the number of lines of each file. Let us call this script
account_report
.
#!/bin/bash
wc –l /etc/passwd
wc –l /etc/group
wc –l /etc/shadow
Running this script generates output as we might expect for the first two instructions:
the number of lines of the two files. However, for the third line, we get this error:
wc:/etc/shadow: Permission denied
Our error message indicates that it was not our script that caused an error but instead
the wc command from within the script. The error arises because the shadow file is not
accessible to any user other than root.
We will explore other errors that may arise as we introduce Bash programming instruc-
tions in later sections of this chapter.
7.3 VARIABLES, ASSIGNMENTS, AND PARAMETERS
7.3.1 Bash Variables
A shell script can use variables. There are two types of variables: environment variables
that, because they have been exported, are accessible from within your script or from
the command line and variables defined within your script that are only available in the
script. All variables have names. Names are commonly just letters although a variable’s
name can include digits and underscores (_) as long as the name starts with a letter or
underscore. For instance, you might name variables
x
,
y
,
z
,
first_name
,
last_name
,
file1
,
file_2,
and so forth. You would not be able to use names like
1_file
,
2file,
or
file 3
(the space is not allowed). Variable names are case sensitive. If you assign the
250
◾
Linux with Operating System Concepts
variable
x
to have a value and then use
X
, you are referencing a different variable. Note
that all reserved words (e.g.,
if
,
then
,
while
) are only recognizable if specified in lower
case. Unlike most programming languages, variable names can be the same as reserved
words such as
if
,
then
,
while
, although there is no reason to do this as it would make
for confusing code.
Variables in Bash store only strings. Numbers are treated as strings unless we specify
that we want to interpret the value as a number. If we do so, we are limited to integer num-
bers only as Bash cannot perform arithmetic operations on values with decimal points
(floating point numbers). Bash also permits arrays, which we examine later in this chapter.
7.3.2 Assignment Statements
In order to assign a variable a value, we use an assignment statement. The basic form of the
assignment statement is
VARIABLE
=
VALUE
No spaces are allowed around the equal sign. Unlike programming languages like C and
Java, the variable does not need to be declared.
The value on the right hand side can be one of four things:
• A literal value such as Hello, “Hi there,” or 5
• The value stored in another variable, in which case the variable’s name on the right
hand side of the assignment statement is preceded by a dollar sign as in $FIRST_
NAME or $X
• The result of an arithmetic or string operation
• The result returned from a Linux command
Literal values should be self-explanatory. If the value is a string with no spaces, then
quote marks may be omitted. If the value is a string with spaces, quote marks must be
included. There are two types of quote marks, single quote marks (‘’) and double quote
marks (“”). These are differentiated below. Here are several examples of assignment state-
ments and their results.
•
X
=
5
• X stores the string 5 (this can be interpreted as an integer value, as will be dem-
onstrated later)
•
NAME
=
Frank
• NAME stores
Frank
•
NAME
=
"Frank Zappa"
Shell Scripting
◾
251
• NAME stores
Do'stlaringiz bilan baham: |