Understanding Perl's Special Variables - To Err Is Human (Page 7 of 11 )
When it comes to dealing with errors, there are a number of variables you
should know about. The first of them is the $? variable, which stores the
error code returned by a call to an external binary, or to the system()
function.
#!/usr/bin/perl
# add a user who already exists
`/usr/sbin/useradd root 2>/dev/null`;
# if error code, return it
if ($?)
{
print "Error code ", $? >> 8;
}
Here's the output:
Error code 9
In case you're wondering about the bitwise operation in the program above -
the value stored in the $? variable is a 16-bit integer, of which the first
8 bits represent the error code returned by the invoked command.
You can also use the
$? & 127
operation to obtain information on the termination signal of the command, and
$? & 128
operation to get a Boolean value indicating whether or not the program
dumped core.
As you may (or may not) know, Perl also allows you to trap errors in a
syntax similar to Java's try-catch() blocks, by enclosing your code in an
eval() block. In case the code within the eval() block produces an error,
Perl stores the error in the $@ system variable without escalating it to
the main program, from whence it may be retrieved for exception-handling
purposes. The following example illustrates:
#!/usr/bin/perl
# attempt to use a file which does not exist
eval( "use Timezone;" );
# check for error
if ($@ ne "")
{
print "The following error occurred: ", $@;
}
In this case, since the call to use() is within an eval() block, the error
returned when Perl is unable to locate the Timezone package will be trapped
by the special $@ variable and will not be escalated upwards to the main
program. You can then write your own exception-handling routine to inspect
$@ and resolve the error appropriately.
Here's the output, with the $@ error-trapping above in action:
The following error occurred: Can't locate Timezone.pm in @INC (@INC
contains: /usr/lib/perl5/5.8.0/i386-linux-thread-multi .) at (eval 1) line 1.
BEGIN failed--compilation aborted at (eval 1) line 1.
You can also catch error messages returned by die() within an eval() block
with the $@ variable - as illustrated below:
#!/usr/bin/perl
# open file
eval( "open(FILE, '/tmp/dummy.txt') or die ('Could not open file');");
# check for error
if ($@ ne "")
{
print "The following error occurred: ", $@;
}
Here's the output:
The following error occurred: Could not open file at (eval 1) line 1.
In the case of Perl functions that use C library calls, you can also access
the error returned by the underlying C library with the special $!
variable. In order to illustrate, consider the Perl open() function, which
uses the C open() call, in a variant of the example above:
#!/usr/bin/perl
# open file
eval( "open(FILE, '/tmp/dummy.txt') or die ('Could not open file');");
# check for error
print "The following error occurred: $!";
Note how, in this case, the error message displayed is the one returned by
the C library, not Perl (compare it with the previous example to see the
difference):
The following error occurred: No such file or directory
Next: A Question Of Ownership >>
More Perl Articles
More By icarus, (c) Melonfire