One hot afternoon, I was assigned the job to e-mail
a bunch of people and asked them to do a survey. Since those are all
busy people, we thought it would be nice to personalize each one instead
of a generic dear sir/madam...
For those who have been in cs (Computer Science not
Counter Strike!) for a while, this is probably pretty easy. But to promote
the use of perl (it's a nice scripting language!), I thought it would
be nice to show how this task can be done in this concise scripting
language. You can think of this as a brief perl tutorial or a simple
perl example.
This is done on a unix/linux system, where perl is
pre-installed. The script is also dependent on the standard mailing
program "sendmail". Theoretically, this can also be done on
Windows, with a perl
interpretor and a mailing
tool.
This is intended for people who have programming background.
I remember the days when I got frustrated when reading some books on
scripting languages that cover stuff like how to write a for loop. I
think I know how to write a loop if I have programming background thank
you very much.
Now I will start discuss the script bit by bit. If
you prefer, you can download the complete
script first.
#!/usr/local/bin/perl
-w
$sendmail
= '/usr/lib/sendmail -i -t';
Change this line to wherever sendmail is located.
This can be found on a unix system by typing whereis sendmail.
$sender
= 'yourname@address.com';
Substitute this line to your address. In Perl,
single quote and double quote are both used to quote strings. The
special characters in a single quoted string does not have to be escaped,
while they have to be escaped in double quoted string. (i.e. "yourname\@address.com"
is equivalent to 'yourname@address.com').
open(CONTACTLIST,'contactlist.txt');
This line opens the file called 'contactlist.txt'.
The first line is the name of person A, the second line of the e-mail
address of person A. The third line is the name of person B, and the
fourth line is the address of person B, etc. In terms of perl syntax,
CONTACTLIST is now the file handle of the contact list file.
$count=0;
Perl variables do not need to be declared before
using them. You don't even have to define the type, and it would know
based on the values you assigned to it. Non-array types (integer,
string, character) variables are prefixed by a dollar sign.
while(<CONTACTLIST>){
<CONTACTLIST> means read a line from CONTACTLIST
and returns true if the read is successful and false otherwise. This
line effectively iterates through the entire file, line by line. The
line that is read is automatically assigned to $_ (a default variable
that Perl assigns to when no variable is specified)
chomp;
chomp is a handy command that removes the end
of line character in the string value assigned to $_
$nameList[$count++]=$_;
Assign the default variable to an element in the
an array called nameList. When nameList is addressed/called as the
entire array, it's prefixed by @ (i.e. @nameList). However, because
we are assigned it to a particular index (which stores a non-array
type), we prefix the whole thing with a dollar sign. (so basically
$(nameList[index])). Note that we do not have to declare the size
of the array beforehand either.
$_=<CONTACTLIST>;
Read another line from the CONTACTLIST file.
chomp;
$nameList[$count++]=$_;
}
%nameList=@nameList;
We need to reference nameList as an array in this
line, so we use the @ prefix on the right. The % prefix means the
variable is an associative array. An associative array is an array
that can take strings as indices. For example, colorArray{'red'}=
'White minus green and blue". What this line does is turn @nameList
(a traditional array in C/C++) into an associate array (using the
same name!). How the conversion takes place is take the first element
in the original array and call it the key, and the element following
it and call it the value. The third element is the key, the fourth
is the value, and so on.
close(CONTACTLIST);
Close the CONTACTLIST file. This is straightforward.
open(MESSAGE,'message.txt');
After we finished reading the list of names and
e-mails, we open the 'message.txt' to read the main content of the
e-mail we are sending.
@entireMessage=<MESSAGE>;
This line shows that <FILEHANDLE> is an
overloaded operator. When it is assigned to a scalar variable (prefixed
by $, or to $_), it reads one line. If it's assigned to a array variable,
it reads the entire file and place each line into a different element
(in order).
while(($recipient,
$address)=each(%nameList)){
This means for each key and value pair in the
associate array, assign the key to $recipient and the value to $address.
#print "Key: $Key, Value: $Value\n";
This line is commented out. (Prefixing by # is
the only way to comment out things in Perl.) This line shows that
in a double-quoted string, the scalar variables will be substituted
with their values. Isn't this smart way to concatenate strings? (It's
like printf in C without arguments!)
$mailbody="Dear $recipient,\n\n";
foreach(@entireMessage){$mailbody.=$_;}
First of all, .= is a concatenate operator. (i.e. $a.=$b is the same as "$a$b"). What this line does is turn the @entireMessage into one big concatenated string
print $mailbody;
Prints out the $mailbody to console so that you can have a look at it.
open(MAIL, "|$sendmail -oi -t")
;
This line sets the environment so that whenever you do print MAIL something in the future, the something is piped to $sendmail (which contains the location of the sendmail program).
print MAIL "To: $address\n";
print MAIL "From: $sender\n";
print MAIL "Subject: AddSubjectLine\n\n";
print MAIL "$mailbody";
The above is the syntax to send a e-mail using sendmail. Basically by piping the above lines to sendmail, the mail will get sent.
close(MAIL);
}
Close the handle since we're done with it.
Last words:
For those who have done some programming, you may realize
what the script is doing is terribly inefficient - for example, it
reads the entire file to an array, and then convert the array into
a string, and then convert it back, etc. Clearly, this is a contrived
example meant to show you some basics of perl. Feel free to contact
me if you have any questions.