Basic Shell Scripting
In many of the other sections of the shell and utilities, we talked about a
few programming constructs that you could use to create a quick
script to perform some complex task. What if you wanted to
repeat that task with different parameters each time? One simple solution is
to is to re-type everything each time. Obviously not a happy thing.
The solution is to create a shell script we can use over and over again, which
is the topic of this section. There are entire books on shell programming and to understand
everything you probably need more material that any single book can provide. Rather
than going through every possible shell constructs, we are going to cover more or
less the basics. One of the things we will be using as a guide is how often a given
construct appears in shell scripts that a standard Linux distribution provides by default
and how important these constructs are to understanding the given script.
To create a shell script, we could use vi or some other text editor
to create the file. However, we could
take advantage of a characteristic of the cat command, which is normally used to
output the contents of a file to the screen. You can also redirect the cat to
another file.
If we wanted to combine the contents of a file, we could do something like this:
cat file1 file2 file3 >newfile
This would combine file1, file2, and file3 into newfile.
What happens if we leave the names of the source files out? In this
instance, our command would look like this:
cat > newfile
Now, cat will take its input from the default input file, stdin.
We can now type in lines, one at a time. When we are done, we tell cat to close
the file by sending it an end-of-file character, Ctrl-D. So,
to create the new command, we would issue the cat command as
above and type in our command as the following:
for j in boat ship yacht
do
find ./letters/taxes -type f | xargs grep -i $j
done
<CTRL-D>
Note that here the secondary prompt, >, does not appear because it is cat
that is reading our input and not the shell.
We now have a file containing the five lines that we typed in that we can use
as a shell script. So, being able to create new scripts with
the cat.
Granted to be able to edit the file
using vi is fairly straight forward. However, I have worked on
a number of systems were vi was disabled for everyone but the administrator or I
accessed the machine through a connection that made using vi
difficult.
In order to fully understand this we need to look at the for-in construct and the
do-done pair. You will find the do-done pair in a number of contexts. In short,
it defines the block of commands to be executed by the preceeding construct. In
this case the for-in construct. You will also find a do-done pair when creating loops
using while, as well as other places.
In the example above, the for-in construct looked like this:
for j in boat ship yacht
In essence this loops through the statements in the do-done block once for each of
the values listed: boat ship yacht. Each time through the loop, the respective
value is assigned to the variable j. So, the first time j=boot, the second time
j=ship and the third time j=yacht.
We did not need to use a single letter here. Instead, we could have used any valid
variable. For example, we could have called it SEARCHWORD, if we wanted.
In our example, the lines within the do-done block are executed three times. Here we only
have a single line, but could have essentially any number of lines within a do-done block.
This example also uses the xargs command. The example here is perhaps
the simplest form you will find xargs. As you can see, it is the end of
the pipe from the find which is simply finding every single
file in the directory ./letters/taxes. Thus, xargs
is getting a list of files feed into it’s standard input. It then creates a command using
grep which searches through each of the files passed through the pipe.
Keep in mind that we have the variable $j which changes during each pass through the loop.
So, the first time through the look the xargs command would look
like this:
xargs grep -i boot
Therefore, this would search through each of the file looking for “boot”. Note that the -i says
to ingore the case.
However, right now, all that we have is a file named newfile that contains
five lines. We need to tell the system that it is a shell
script that can be
executed. Remember in our discussion on operating system
basics that I said that a file’s permissions
need to be set to be able to execute the file. To change the
permissions, we need a new command: chmod.
(Read as “change mode” because we are changing the mode of the file.)
The chmod command is used to not only change access to a
file, but also to tell the system that it should try to execute the
command. I said “try” because the system would read that file, line-by-line,
and would try to execute each line. If we typed in some garbage in a shell
script, the system would try to execute each line and would probably report “not found” for every line.
To make a file execute properly, we need to give it execute permissions.
To give everyone execution permissions, you use the
chmod command like this:
chmod +x newfile
Now the file newfile has execute permissions, so, in a sense,
it is executable. However, remember that I said that with a shell scripts, the system would
read each line and try to parse it. In order for a shell
script to function correctly, it also needs to be readable by
the person executing it. In order to read a file, you need to have read
permission on that file. More than likely, you already have read
permissions on the file since you created it. However, since we gave everyone
execution permissions, let’s give them all read permissions as
well, like this:
chmod +r newfile
You now have a new command called newfile. This can be executed just like
any the system provides for you. If that file resides in a directory somewhere
in your path, all you need to do is type it in. Otherwise, (as we talked about
before) you need to enter in the path as well. Keep in mind that the system does
not need to be able to read binary
programs. All it needs to be able to do is
execute them. Now you have your first shell
script and your first self-written Linux command.