_______________________________________________________________

The Perl Almost Weekly Manual By Ankit Fadia ankit@bol.net.in

_______________________________________________________________

@ARGV

Till now we have learnt about only one special Variable, the $_ variable. Another useful variable is the @ARGV variable which contains a set of elements of all command line arguments provided to the Perl Program. The first command line argument can be found at $ARGV[0], the second at $ARGV[1] and so on. Let's suppose a Perl Program was called using three command line arguments, which are

Ankit, Fadia, Anki123. Then @ARGV would contain Ankit, Fadia and Anki123, with $ARGV[0]=Ankit, $ARGV[1]= Fadia and $ARGV[2]= Anki123.

For Example,

The following PERL program takes the number which was passed as a command line argument, then multiplies this argument with 4 and finally displays the result on the screen.

$number = $ARGV[0];

print $number *4;

Output:

C:\perl>perl filename.pl 5

20

Not all functions assume $_ to be the default variable, some functions take @ARGV instead. For Example, the shift( ) function. What the shift( ) function does is remove and return the leftmost or the first argument of @ARGV. To understand the use of the shift( ) function, consider the following example.

In this PERL program ,we assume that the User Passes two arguments, the Program then takes the two arguments adds them and then displays the sum on the screen.

$first = shift;

$second = shift;

print $first + $second;

Output:

C:\perl>perl filename.pl 3 5

8

Input Output

Until Now we know of only two kinds of data types-: Scalars and Arrays. Well in this chapter, we will learn about a new third kind of data type called Filehandles. These filehandles act as a bridge between the Perl Program and other files, directories or other programs.

In fact, we have already come across file handles in the earlier chapters, without even noticing it. Remember that we used the angle brackets < >, for two purposes: to read files and to get User Input. Now in both the cases, the angle brackets automatically without you knowing of it, opened a filehandle.

The Standard Perl filehandles are-:

 

STDIN Standard Input Used to Get User Input

STDOUT Standard Output The Program output, which is usually displayed on the screen.

STDERR Standard Error Error Messages to be displayed on the Screen

Just like STDIN is used to get User Input and ARGV is used to read command line data. All this might seem a bit confusing, but believe me, it really is not. Read on to understand better.

Say you give a command like:

$varname= < >;

then PERL automatically fills the angle brackets with either STDIN or ARGV. But how does PERL decide which handle should be inserted? Good Question. You see, whenever PERL comes across angle brackets, it checks to see whether there is still data left to be read from the command line files. If there is data left, then the angle brackets behaves as <ARGV> else they behave as <STDIN>.

We can also manually differentiate between the two by mentioning either one of them within the angle brackets. So basically we can say that the code <FILE> will read data from FILE.

Opening Files For Reading

Well now that you know what file handles do, lets learn how to open a text file to read it's data and print this read data on the screen. The following code does just that-:

open(SITES, "sitelist.txt"); # Open sitelist.txt and name the connection SITES

while (<SITES>) {

print; # Read the next line from SITES and print it on the screen

}

Now let's analyze each line of the code snippet. In the first line, we use the open ( ) function (discussed in detail later) to open the file sitelist.txt and give the connection a friendly name of our choice, in this case we name the connection SITES. We can give it any name of our choice, even something like your own name or simply 'a'.

The second line is the same as

while($_= <SITES>);


We are simply making better, more efficient scripts. It basically reads the next line of sitelist.txt using the opened connection, SITES. This line is then assigned to the default variable $_ , which is finally printed by the third line. Perl reads one by one each line of the file opened.

Now let's say if the file sitelist.txt does not exist, then normally PERL displays a cryptic difficult to understand error message which is of no use to a novice to deduce what went wrong. How can we display our own customised error messages instead of using the cryptic PERL error messages? Well the die ( ) function holds the key.

The basic syntax of the command is-:

 

die(STRING): This code exits the program with the current value of the special variable $! (Discussed Later) and prints STRING on the screen.

Now let's take an example to see how we can use the die( ) function effectively.

Consider the following snippet of code-:

open (FILE123, "first.txt") | | die "File Not Found";

while (<FILE123>) {

print;

}

The above program attempts to open the first.txt text file and if it cannot do so for some reason, it displays the cutomised error message, File Not Found on the screen.

Another Special Variable: $!

Earlier I had mentioned a new kind of special variable, the $! Variable.

The $! Or $ERRORNO or $OS_ERROR Variable contains the system error code. In Numeric context ($!) it contains the error number and in character context ($ERRORNO or $OS_ERROR) it contains the error message.

For Example,

print $!; #Prints current Error Number

print $ERRORNO; #Prints Error Message associated with the current Error Number

The Error Number to Error Message table is as follows:

 

  1. Not Owner
  2. No Such File or Directory
  1. Input/Output Error
  1. Permission Denied
  1. File Exits
  1. No Space Left on Drive

This variable is normally is used in the following context;

Open(FILE123, "xyz.doc") || die "File Not Found: $!"

Will display something like the following error message if the file xyz.doc does not exist:

File Not Found: 2

Sometimes, when an error occurs, instead of exiting entirely from the program we might need to display only a Warning Message advising the user what to do next as an error has occurred. This is where the warn ( ) function comes in. This function too works like the die ( ) function the only difference being that the program is not exited.

For Example,

warn("Caution!! System Resource Low. Please Close some programs before continuing");

 

Till now we have learnt only how to read from a file, now let’s learn how to write or even append to a file. Again we make use of the lovely function open( ). Its basic syntax is as follows-:

open(FILEHANDLE, FILENAME): Opens the file FILENAME and gives the connection the name, FILEHANDLE.

If the open ( ) function is successful it return the TRUE value else it return UNDEF.

Whether a file has been opened for only reading, only writing, appending, or both writing and reading depends on the character at the beginning or preceding FILENAME.

If FILENAME begins with < (or nothing) the file is opened for Reading only.

If FILENAME begins with > then the file is opened for Writing only.

If FILENAME begins with >> then the file is opened for appending.

If FILENAME begins with +(i.e. +>, <+ or +>>) then the file is opened for reading and

writing(appending).

If FILENAME is - then STDIN is opened

If FILENAME is >- then STDOUT is opened

The following are some Practical examples, that will make you understand the various characters better-:

open(FILE, ">>$filename") or die" File not Found"; #File opened for Appending

open(FILE, "+<$filename") or die" File not Found"; #File opened for both reading and writing.

open(FILE, "+>$filename") or die" File not Found"; #File opened for both reading and writing

open(FILE, ">$filename") or die" File not Found"; #File opened for writing.

NOTE: When you try to open a file with the > character then PERL checks to see if the file by the specified filename exists or not. If yes then the File is overwritten else a new file by the specified filename is created.

The close( ) function is used to close a file connection using the open ( ) function. The basic syntax of the close( ) function is as follows:

Close(FILEHANDLE);

Examples:

print "USERNAME:";

chomp ($user= < >);

print "Password:";

chomp($pass= < >);

open(LOGFILE, ">>log.txt") or die " Please Re Login";

close(LOGFILE);

The above code simply logs or appends the Usernames and Passwords typed by the User to a log file, log.txt and then finally closes the File Handle associated with it.

The following PERL program logs all keystrokes of the User until he types EXIT\n.

While(10) {

$input = <>; #Infinite Loop

last if $input eq "exit\n"; #Exit loop when User types Exit followed by Enter.

open(FILE, ">>xyz.txt");

print FILE $input; # Print data typed by User in the file xyz.txt

}

close FILE;

MOVING AROUND IN A FILE

Now that we know how to open a file for various purposes, how can we move around within a file and how can we tell where you are?

You see, whenever a file handle is used, it has an associated file pointer. When we open a file, the file pointer by default points to 0. This file pointer changes automatically accordingly as we move or read data from the file using the filehandle. This process is automatic and occurs without any User intervention.

But sometimes, we manually want to change the position of the file pointer and make it point elsewhere. This is when the seek( ) and tell( ) functions come into the picture.

seek( )

Basic Syntax of the seek command is:

seek(FILEHANDLE, STEPS, FROM); :Moves the file pointer of the FILEHANDLE to number of STEPS from FROM.

Note: File Positions are measured in Bytes.

The value of FROM can be 0 for the beginning of the file, 1 for the current position and 2 for the end of the file.

The following example will really make you comfortable using the seek( ) command:

seek(FILE, 0, 0); # moves to beginning of file

seek(FILE, 157,0); #moves to 157 bytes from the beginning of the file.

seek(FILE,45,1); #moves 45 bytes ahead.

seek(FILE, -45,1); #moves 25 bytes behind.

seek(FILE,200,2); #moves 200 bytes from the End of File.(EOF)

I hope by know you would probably know the seek( ) command like the back of your hand.

tell( )

The tell() command returns the current position of the file pointer.

For Example,

print tell(FILE);

prints the current position of the file pointer.

Truncating Files

The truncate( ) function is used to truncate or shorten a file to the specified number of bytes. Its basic syntax is:

truncate(FILE, NUM); :Shortens the FILE to NUM number of bytes.

For Example,

truncate("xyz.txt", 100); #Shortens xyz.txt to 100 bytes.

The same above result can also be achieved by the following lines of code:

open(FILE, "+<xyz.txt);

truncate(FILE, 100);

Deleting Files

To delete files, we use the unlink( ) function whose basic syntax is as follows:

unlink(FILENAMES); :Deletes File Names

This function returns the number of files successfully deleted.

For Example,

unlink "log.txt"; #Deletes log.txt

This PERL function can be very useful to delete temporary files from the hard disk and save space. Consider the following PERL program which deletes all .bak, *.~ and *.tmp files are the disk.

$name = shift;

@old = ($name. '.bak', $name. '.~', $name. '.tmp');

foreach(@old) {

Print "Deleting $_";

}

unlink @old;

FILE TESTS

Files come in all sizes, properties and types. PERL has certain file tests which inspect File characteristics and properties.

File tests are very funny looking with a single hyphen followed by a special character.

The basic format of file tests is as follows-:

-TEST FILE: is true only if FILE satisfies TEST. FILE can be either a filename of a filehandle.

The following is a complete list of file tests and their meanings-:

FILE TEST Meaning

-e File Exists

-f File is a plain text

-d File is a directory

-T File is a text file

-B File is a Binary File

-r File is readable

-w File is writable

-x File is executable

-s Size of File(Returns Number of Bytes)

-z File is Empty i.e. is of Zero Bytes

 

Now that you have the complete list of files tests, lets see how to practically make use of them. The following is a collection of examples which will make file tests easier to understand.

Examples,

if (-d "/etc") {

print "Directory Exists"; #Prints message if /etc is a directory

}

The following is an example of a PERL program which checks if a file exists.

$file = shift;

if(-e $file){

print "$file Exists. \n";

}

Every file is either a -T or -B. Perl looks at the beginning of the file. If there are a lot of strange characters, then it is a Binary File else it is a Text File. But empty files satisfy both the -T and -B condition. The following Perl Program checks to see if a file is empty or not.

$file = shift;

if(-z $file){

print "$file Exists. \n";

}

 

The stat( ) function

The file tests that we have learnt till now check only a single specific property of a file, however on the other hand, the stat( ) function returns an array of 13 file statistics.

The syntax of the stat( ) command is-:

stat(FILE) : It returns a 13 element array containing the vital or important statistics of the FILE. The FILE can either be a FILE or a FILEHANDLE.

The elements of the stat array are-:

Index Value

  1. The Device
  2. The File's inode
  3. The File's mode
  4. The Number of Hard Links to the File.
  5. The user ID of the file's owner
  6. The Group ID of the file
  7. The raw device
  8. The size of the file
  9. The last time the file was accessed
  10. The last time the file was modified
  11. The last time the status of the file was changed
  12. The block size of the system
  13. The Number of blocks used by the file

Let's take an example in which we use the stat( ) array to compute the size of a file.

$file = shift;

$size = (stat($file))[7]; #Returns the eight element of the stat( ) array.

print "Size is: $size";

 

The same above result can be obtained by using the see( ) and tell( ) functions.

$file = shift;

open(FILE, "$file");

seek(FILE,0,2);

$size = tell(FILE);

print "Size is: $size";

There is yet another method of finding out the size of a file, using the file tests.

$file = shift;

$size = (-s $filename);

print "Size is: $size";

Reading Bytes and not Lines

Normally when a Perl program opens a file for reading, it reads a line one by one. However sometimes we need to read bytes and not lines. This is when the read( ) function comes into picture.

The basic syntax of the read( ) command is:

read(FILEHANDLE, VARNAME, BYTES, OFFSET) : Reads BYTES number of bytes starting from OFFSET in FILEHANDLE, placing the result in VARNAME. If OFFSET is not specified, then PERL starts reading from the beginning of the file.

For Example,

open(FILE, "xyz.log") or die "File not found";

read(FILE, $text, 1000);

print $text;

The above snippet of code reads the first 1000 bytes of the file xyz.log and places them into the variable $text and finally prints it on the screen.

The read function can sometimes be less accurate. By that what I mean to say is that sometimes, it reads more bytes than you want it to, due to differences in the Buffer of the system. If this is unacceptable, you should instead use the sysread( ) function, whose basic syntax is as follows:

sysread(FILEHANDLE, VARNAME, BYTES, OFFSET) : Reads BYTES number of bytes starting from OFFSET in FILEHANDLE, placing the result in VARNAME.

This function is almost the same as the read() function accept the fact that it is more accurate and hence sometimes preferable.

Similarly sometimes you may need to write a certain number of bytes from a scalar to a file. For that PERL has the syswrite( ) function, whose syntax is:

syswrite(FILEHANDLE, VAR, BYTES, OFFSET): writes BYTES number of bytes of data from VAR starting at OFFSET to FILEHANDLE.

Both sysread( ) and syswrite( ) return the number of bytes actually read or UNDEF if an error occurs.

The getc( ) function

This functions does what its name suggests, it gets the next character from the filehandle. Its syntax is:

getc(FILEHANDLE): returns the next character from FILEHANDLE.

When the End of File or EOF is reached the value of getc( ) is empty.

ACCESSING DIRECTORIES

Just as for files you have the open( ) and close( ) functions, for directories, you have the opendir( ) and closedir( ) functions. Their syntax is as follows:

opendir(DIRHANDLE, DIRNAME):opens the directory DIRNAME.

closedir(DIRHANDLE): closes DIRHANDLE

For Example,

opendir(DIR, "/etc"); #opens the /etc directory

The readdir Function

This is the most used function associated with directories and it's syntax is:

readdir(DIRHANDLE): returns the next file from DIRHANDLE (in scalar context) or the rest of the files (In ARRAY context). If there are no more files, then it return undef.

The following Perl Program uses the opendir( ), closedir( ) and readdir( ) functions to list all files in a particular directory.

$name = shift;

opendir(DIR, $name) or die "Directory invalid: $! \n";

@listoffiles = readdir(DIR);

closedir(DIR);

foreach $file (@listoffiles) {

print "$file\n";

}

Output:

C:\perl> filename.pl /etc

Ankit.log

Ankit.txt

Passwd.txt

Other Directory Functions

The following is a list of syntax and use of some other popular Directory Functions:

telldir(DIRHANDLE): returns the position of DIRHANDLE.

seekdir(SIRHANDLE, POSITION): sets DIEHANDLE to read from POSITION which should be

something like the value returned by telldir( )

rewinddir(DIRHANDLE): sets DIRHANDLE to the top of the directory.

mkdir(DIRNAME, MODE) : Creates Directory with the name DIRNAME and mode specified by MODE(Unix).

rmdir(DIRNAME, MODE): Deletes the directory DIRNAME.

chdir(DIR): changes the working directory to DIR.

chroot(DIR): Changes the root directory for the current process to DIR. Only root is allowed to do this.

 

Well this is the end of the Perl Section. These Perl Manuals were not aimed at making you a Perl guru but to teach you Perl to that extend to which you could write Useful Programs. For further free Perl Manuals join my mailing list by sending an email to: programmingforhackers-subscribe@egroups.com There I will distribute manuals on both Perl and C which will make you proper experts.