Many of the uninitiated who first see Perl immediately become intimidated by the arcane symbols, and strings that look as though a cat walked across the keyboard. If you're one of these people, fear no more. I myself was one of those people. Yet even I am now able to conquer common sysadmin problems large and small, using nothing more than a few lines of Perl. On occasion, I'm even impressed at the feats of greatness that Perl and I can pull off. In the end, sysadmins like Perl because Perl makes them look good.
Ah, but where to start? For me, the easiest way to get started is to "scratch an itch," so to speak. If you don't have anything urgent, porting old shell scripts to Perl provides a great exercise for learning how things are done in Perl. But of course, it helps if you have some clue of how the world looks through Perl-tinted glasses, so let's have a look at some basics.
What all the funny symbols mean
Perl uses lots of quirky symbols that look intimidating at first. However, once you understand what they mean, you'll realize that they are there to help you. These first three are used to indicate that a particular variable is of a particular type:
$scalar
@array
%hash
Any time you see a single "$" followed by a name, it's a scalar variable. A scalar variable can hold any type of value. Strings, numbers, floating point numerics, and even references to locations in memory can all be stored in scalar variables. These are probably the most frequently used variable types, since practically anything can be stored in them.
A single "@" indicates that the variable is an array. I tend to think of arrays as nothing more than a potentially random selection of scalar values. They are indexed numerically for you by Perl so that you can easily reference individual bits within the array later in your script. This one needs an example:
@days = ( 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday',
'Saturday');
Once I've declared my array and populated it, referencing individual values is
as easy as asking for it by its index value. Index
numbers start at "0," so if I'm looking to get back "Tuesday," I'd put the line
print $days[2]; in my script.
A single "%" in front of a variable name signifies that it is a hash. A hash is just slightly more complicated than an array, but affords you the flexibility of assigning your own index, instead of using the default numeric ones Perl generates for you. So, suppose I need an array of user names, and an array of Unix shells, but I need the shells to be matched up with the right users. Instead of using two arrays and writing the code to match up values from them, I can just make the username the index for my hash, and make the shell of choice the value:
%usershell = ( jimi => '/bin/bash', eric => '/bin/tcsh', eddie => '/bin/csh',
billy => '/bin/zsh' );
So now, if I want to know the shell assigned to "eric", I can just ask for it
(almost) by name: print $usershell{'eric'};.
More symbol quirkiness, clarified
Why did I use a "%" to assign a hash, and a "$" when I wanted to print a value from it? This is initially confusing. Notice also that I did the same thing with our arrays, above. The reason is that, when I ask for a particular value of a hash or an array, I'm asking for a piece of scalar data, not an entire hash or array. Because I want a scalar value back, I use the "$," which as we discussed before indicates a scalar value.
The observant will then ask, "Well, you said that the symbols indicate the type of variable it is -- how do I know whether you're asking for a scalar value from a hash or an array?" The answer lies in the type of brackets used to ask for the value. As you can see in the above examples, the curly braces are used for hash values, and square brackets are for arrays.
But what if you have to reference something that you haven't explicitly defined
in your script? Symbols to the rescue! Probably the most common symbol that I
haven't covered yet is $_. This is sort of a placeholder or
"default" variable used, for example, inside a subroutine to reference the
arguments passed to it. Since you don't know what's being passed to a
subroutine when you write it, you can just use this variable to represent the
parameters. Sometimes, $_ can be implied -- for example, if you
ever see a single line of Perl code which says, simply print;, the
$_ is actually implied, though it's not incorrect to put it there if
it makes things clearer for your brain.
Loops in Perl
I've coded in numerous languages, ranging from C/C++ to PHP and even a little Python. For loops, I still like Perl the best (though PHP 4 is almost identical in this respect). While Perl has a rather impressive array of looping structures, for brevity, I'll cover just two common loops: for and while.
The "for" loop is famous for allowing you to control iteration based either on an arbitrary number or value you invent, or on a value derived from somewhere else in your code. Here's a simple for loop that uses an arbitrary number I've created to determine the number of times the loop executes:
for ($count = 1; $count <= 10; $count++)
{
print "$count\n";
}
This loop simply prints the numbers 1-10, with a line break after each number. Of course it's really quite rare that you can just make up a number like that. Generally, you want the number of loop executions to be based on some dynamic variable so you don't have hard-coded constants strewn about your code that may need to be changed at some point (causing you work, thereby defeating the purpose of scripting in the first place!). Here's something more realistic:
@users = ('eric', 'billy', 'eddie', 'yngwie');
for ($i=0; $i < $#users; $i++)
{
  print "$users[$i]\n";
}
In the above example, I started with an array containing four values. I
initialized $i to zero. Each time through the loop, I
check and see if $i is less than the highest index value in the
@users array. If it is, I keep going, incrementing $i
by 1 each time through. Note that I snuck yet another symbol in here:
$#, which returns the highest index value in an array. Since
arrays are indexed starting at 0, the value should always be the number of
values in the array, minus one.
The while loop
The while loop tests the input, and then executes statements based on the outcome of the test. This is often useful in situations where input is read from a file or from the keyboard, and you want to act upon each piece of input without knowing ahead of time what it is or how much of it there will be. Here's an example:
open (PASSWD, '</etc/passwd') or die "Can't open file: $!";
while (defined($acct = <PASSWD>)) {
print "$acct";
}
This does essentially the same thing as cat /etc/passwd would do at the
command line. The first line opens the /etc/passwd file and assigns a handle
name to it called PASSWD. Then, I assign a variable to the value coming in
from the handle (basically, a line of data from the /etc/passwd file), and if
there is a value there, the loop executes. As soon as there ceases to be data
in $acct, the loop stops executing.
In conclusion
Don't say I've teased you; I've not even written enough about Perl to accomplish that. I'd need another 5,000 words to feel like I've given you even half of a clue. However, I do hope that what I presented here will make the task of reading and writing some simple Perl code a little less daunting. If demand dictates, I'll continue in a future article with more advanced topics and regular expressions.
Note: Comments are owned by the poster. We are not responsible for their content.
<TT>for $i (0<nobr> <wbr></nobr>.. $#array) {
print "$array[$i]\n";
}</TT>
Oreilly Books have produced, I think, the best collection of PERL books. (<A HREF="http://perl.oreilly.com/" title="oreilly.com">http://perl.oreilly.com/</a oreilly.com>)
The best place to start would be 'Learning Perl'. It is presented in a step by step manner taking you through the basics of PERL. It also teaches the most critical part of PERL: Think Like Larry!
Larry Wall, for the most part, created PERL and it helps to understand why he created it the way it is. Larry also co-wrote the 'Programming PERL' and it is the BEST single resource for information regarding PERL.
Please, if you're interested in PERL, check out Oreilly Books. They have helped me find that missing part more times than I care to admit.
--
Baelbouga
<TT>@users = ('eric', 'billy', 'eddie', 'yngwie');Semicolons are required. Managing to confuse Perl beginners about how to print out *all* the values from an array is not!
for ($i=0; $i <= $#users; $i++)
{
print "$users[$i]\n";
}</TT>
<TT>@users = (eric, billy, eddie, yngwie);
foreach (@users)
{
print "$_\n";
}
or
@users = (eric, billy, eddie, yngwie);
foreach my $user (@users)
{
print "$user\n";
}
or
@users = (eric, billy, eddie, yngwie);
print "$_\n" foreach @users;</TT>
Disapointing, No Book Resources
Posted by: baelbouga on July 07, 2004 07:42 PMOreilly Books have produced, I think, the best collection of PERL books. (<A HREF="http://perl.oreilly.com/" title="oreilly.com">http://perl.oreilly.com/</a oreilly.com>)
The best place to start would be 'Learning Perl'. It is presented in a step by step manner taking you through the basics of PERL. It also teaches the most critical part of PERL: Think Like Larry!
Larry Wall, for the most part, created PERL and it helps to understand why he created it the way it is. Larry also co-wrote the 'Programming PERL' and it is the BEST single resource for information regarding PERL.
Please, if you're interested in PERL, check out Oreilly Books. They have helped me find that missing part more times than I care to admit.
--
Baelbouga
#