Online Book Reader

Home Category

Running Linux, 5th Edition - Matthias Kalle Dalheimer [415]

By Root 1442 0
these various languages into complex arrangements, often entailing sed scripts piping into awk scripts piping into shell scripts and eventually piping into a C program. Perl gets rid of the common Unix philosophy of using many small tools to handle small parts of one large problem. Instead, Perl does it all, and it provides many different ways of doing the same thing. In fact, this chapter was written by an artificial intelligence program developed in Perl. (Just kidding, Larry.)

Perl provides a nice programming interface to many features that were sometimes difficult to use in other languages. For example, a common task of many Unix system administration scripts is to scan a large amount of text, cut fields out of each line of text based on a pattern (usually represented as a regular expression), and produce a report based on the data. Let's say we want to process the output of the Unix last command, which displays a record of login times for all users on the system, as so:

mdw ttypf loomer.vpizza.co Sun Jan 16 15:30 - 15:54 (00:23)

larry ttyp1 muadib.oit.unc.e Sun Jan 16 15:11 - 15:12 (00:00)

johnsonm ttyp4 mallard.vpizza.c Sun Jan 16 14:34 - 14:37 (00:03)

jem ttyq2 mallard.vpizza.c Sun Jan 16 13:55 - 13:59 (00:03)

linus FTP kruuna.helsinki. Sun Jan 16 13:51 - 13:51 (00:00)

linus FTP kruuna.helsinki. Sun Jan 16 13:47 - 13:47 (00:00)

If we want to count up the total login time for each user (given in parentheses in the last field), we could write a sed script to splice the time values from the input, an awk script to sort the data for each user and add up the times, and another awk script to produce a report based on the accumulated data. Or, we could write a somewhat complex C program to do the entire task—complex because, as any C programmer knows, text processing functions within C are somewhat limited.

However, you can easily accomplish this task with a simple Perl script. The facilities of I/O, regular expression pattern matching, sorting by associative arrays, and number crunching are all easily accessed from a Perl program with little overhead. Perl programs are generally short and to the point, without a lot of technical mumbo jumbo getting in the way of what you want your program to actually do.

Using Perl under Linux is really no different than on other Unix systems. Several good books on Perl already exist, including the O'Reilly books Programming Perl, by Larry Wall, Randal L. Schwartz, and Tom Christiansen; Learning Perl, by Randal L. Schwartz and Tom Christiansen; Advanced Perl Programming, by Sriram Srinivasan; and Perl Cookbook, by Tom Christiansen and Nathan Torkington. Nevertheless, we think Perl is such a great tool that it deserves something in the way of an introduction. After all, Perl is free software, as is Linux; they go hand in hand.

A Sample Program

What we really like about Perl is that it lets you immediately jump to the task at hand: you don't have to write extensive code to set up data structures, open files or pipes, allocate space for data, and so on. All these features are taken care of for you in a very friendly way.

The example of login times, just discussed, serves to introduce many of the basic features of Perl. First we'll give the entire script (complete with comments) and then a description of how it works. This script reads the output of the last command (see the previous example) and prints an entry for each user on the system, describing the total login time and number of logins for each. (Line numbers are printed to the left of each line for reference):

1 #!/usr/bin/perl

2

3 while () { # While we have input...

4 # Find lines and save username, login time

5 if (/^(\S*)\s*.*\((.*):(.*)\)$/) {

6 # Increment total hours, minutes, and logins

7 $hours{$1} += $2;

8 $minutes{$1} += $3;

9 $logins{$1}++;

10 }

11 }

12

13 # For each user in the array...

14 foreach $user (sort(keys %hours)) {

15 # Calculate hours from total minutes

16 $hours{$user} += int($minutes{$user} / 60);

17 $minutes{$user} %= 60;

18 # Print the information for this user

Return Main Page Previous Page Next Page

®Online Book Reader