CSE271 Lab 7: Shell Programming

Introduction

On Friday and Monday, we introduced shell scripting and regular expressions. Today we will work through some scripting exercises, and in the process, also learn about the ability to schedule jobs in unix systems.

A simple shell script

Let's begin by writing a simple shell script. Edit a file called stamp.sh, which should be a shell script that creates (or overwrites) a file called timestamp with the current date and time. You can run it with bash stamp.sh. Emacs, like any editor, will create a file that is readable and editable, but not executable by default. To make the file containing the script executable, you'll have to change the permissions on it. The chmod command lets you reset the permissions of a file. Let's just use to make it executable. Remember that you can use ls -l to see the permissions associated with a file.

Now we should change the script to always write to the same file. Perhaps your script already does that, but most scripts would just write to a file named 'timestamp', which would create a different file when the script is executed while in a different directory. So to make the script always write to the same file, either the script needs to use cd to get into the right directory, or else the script should specify the target file with an absolute path. So for me, I would need to write to the file /home/bdd3/timestamp. Once that change has been made, I can execute the file from anywhere on the filesystem, and it will always write to the same timestamp file.

Getting a script to run on schedule

UNIX has great support for getting scripts to run on a specific schedule. There are two common mechanisms. The first is the at(1) command, which schedules a particular job (often a script) to execute once at a particular time in the future. We'll come back to that one shortly. The second is the cron system, which allows you to schedule jobs to run repeatedly, perhaps every day, or every hour, or every Monday at 6:14am, etc. The cron system uses a set of crontables -- one per account on a given machine, that lists the jobs to be run, and when. Any user can set up jobs in their own crontab(1) file---type crontab -e to edit yours (which should be empty). (Note that crontab -e will automatically open an editor for you, which will be vi unless you have set the EDITOR environment variable to be a different value, such as with a export EDITOR=emacs statement.) Here is an example of the crontab for the printing subsystem: The first five fields express when to run, and the remainder is the command (or set of commands, in this case) to run. Details of how to express a time are available in the crontab man page. Looking at the rest, you can see that there are multiple shell commands separated by semicolons. In fact, the sequence of commands are only separated into multiple lines for easy presentation here---in the actual crontab entry, they are all on a single line. The only expression that might be new is >file, which is simply a shorthand for touch file.

Here is another crontab, running on the system in my lab that makes backups of important files:

The first entry runs at 1 minute past the hour, every third hour of the day (e.g., 12:01, 3:01, 6:01, etc.). It is a script that creates a snapshot of all user files. The daily script take the oldest hourly snapshot and adds it to the daily snapshots, every day at 2:02am. The weekly script is similar, taking the oldest daily snapshot and moving it to the weekly snapshots, but only runs on Sunday mornings. The mysql dump script makes a backup of the mysql database every day at 4:02am.

OK, back to the first, simpler method of scheduling a single job. This is the approach that I use to collect your homeworks and projects. I use at to schedule a script to run just after midnight of the day a project is due.

Let's now use at to schedule your stamp.sh script to be run. Check the current time on your system, and then schedule your job to run in a few minutes. Here is how I scheduled mine:

The only thing that does not show up above is that in order to finish the at job, I typed CTRL-D on a line by itself (to which the system responded with <EOT>). Later, after the time had passed, I checked it: Don't be too worried about making mistakes in scheduling or in the command to run. If you mistakenly create an at job that you would like to delete, you can do so. First, list all your pending at jobs with atq. Then use atrm to remove the job you identify (using the job number). Here is an example: Finally, after the scheduled time, verify that your job has run (make sure it is no longer in the at queue) and see that the timestamp file has the correct timestamp in it.

Regular expressions in emacs

On Monday we introduced globbing and regular expressions. We saw a few regular expressions used in grep. Today we see how regular expressions are also used in editors.

UNIX editors such as vi and emacs also support regular expressions to search and transform files. In emacs, M-C-S will allow you to type a regular expression and interactively find the next one (C-S will move to the next, as with regular search). M-X replace-regexp will prompt for a regular expression for matching, and then prompt for the replacement string.

Now try it yourself. Start emacs, and place five lines of text "Lehigh X" (without the quotes and where X is the line number, 1-5) into a file. Now use the regex "L.*igh [0-9]" and C-S to see that it matches each one.

Regular expressions in grep

Grep can find lots of useful information for us in a file. Given the file datebook.txt, determine the various grep commands that will Finally, write a short shell script that will ask the user for the name of the person to look up in the databook.txt file, and then output the line or lines that match.
Last revised: 27 February 2013, Prof. Davison.