Home / Alt manpages / perltrap(1)

  • perltrap(1)
  • User command
  • linux

Audit Perl Scripts with the perltrap Checklist

You will use perltrap(1) as a focused review checklist for Perl scripts, then run small checks that expose the most common assumptions. The page is documentation, not a command that rewrites your code. On this machine it comes from perl-doc version 5.38.2-3.2ubuntu0.6 and describes Perl v5.38.2. Allow about fifteen minutes for a short script, or longer if it reads input and mixes several programming languages.

You need a shell and Perl. The examples are ordinary, unprivileged commands. They print values or diagnostics and do not alter files, services or interpreter settings.

1. Confirm the installed guide

Read the local manual before applying advice from a different Perl release. The manual is the authoritative reference for this installed package, and its first warning is practical: enable warnings, use strict code, and read the changes for the Perl version you are running.

$ command -v perl
/usr/bin/perl
$ perl -v | sed -n '1,4p'

This is perl 5, version 38, subversion 2 (v5.38.2) built for x86_64-linux-gnu-thread-multi
$ man perltrap

Checkpoint: if man perltrap is unavailable, install the documentation package through your normal system administration process. Do not copy examples from memory while the local manual is missing.

2. Put warnings and strict mode at the top

Start a script with lexical warnings and strict checks. They catch different classes of mistakes: warnings report suspicious behaviour, while strict mode rejects several ambiguous or unsafe constructs during compilation.

use strict;
use warnings;

my $name = 'Ada';
print "hello $name\n";

Check a file without running it by using Perl's compile-only switch:

$ perl -c example.pl
example.pl syntax OK

This is a read-only check of the source. It still parses the whole program, so a failure can be reported before any normal runtime action. Fix the first diagnostic, then run the check again.

3. Check which value is being compared

Perl uses different operators for strings and numbers. Use eq, ne and their string-ordering relatives for text. Use ==, != and numeric ordering for numbers. A shell or another language may have taught you a different set of operators.

use strict;
use warnings;

my $answer = '10';
print "text match\n" if $answer eq '10';
print "numeric match\n" if $answer == 10;
$ perl comparison.pl
text match
numeric match

Checkpoint: for every comparison in a ported script, ask whether both operands are text, both are numbers, or one is being converted. Do not change an operator merely to silence a warning. Decide what the input means first.

4. Inspect input loops and the default variable

A Perl program runs once unless you create a loop. The -n and -p switches provide implicit input loops for command-line filters, but an ordinary script needs an explicit loop. The manual also warns that a line read is normally in $_, and normally retains its newline.

$ printf 'red\nblue\n' | perl -ne 'chomp; print "$_\n"'
red
blue

In a file, make the assignment and newline handling visible:

use strict;
use warnings;

while (my $line = <STDIN>) {
    chomp $line;
    print "$line\n";
}

This avoids a common distraction: <FH> is a readline operation, not the name of a filehandle. A bare read outside a useful condition can discard the value. Also remember that the current input line is not automatically split into fields. Split it explicitly when that is what the program requires.

5. Review operators that look familiar

Several traps in perltrap are visual lookalikes. Matching uses =~, not assignment with =. Exponentiation uses **, while ^ is bitwise XOR. Concatenation uses a dot, not an empty string. C and C++ developers should use elsif, last and next for the corresponding control-flow jobs.

$ perl -e 'my $x = "perl"; print "matched\n" if $x =~ /erl/; print 2 ** 3, "\n"; print "a" . "b", "\n"'
matched
8
ab

Keep parentheses around unfamiliar expressions while reviewing them. Perl builtins can have unary or list-operator behaviour, and context can change the result of an operation. A line that looks plausible is not proof that it receives the context you intended.

6. Check arrays, hashes and scopes

The checklist calls out zero-based indexes, the difference between numeric and string keys, and the fact that merely referring to a hash value does not create it. It also distinguishes my from local: my creates a lexical variable, while local temporarily changes a global value and can produce dynamic-scope side effects.

use strict;
use warnings;

my @colours = ('red', 'blue');
my %count = (red => 2);

print "$colours[0]\n";
print "$count{red}\n";
print "missing\n" unless exists $count{green};

When iterating a hash, say whether you want keys or values. The safe, readable form is for my $key (keys %hash). Writing a hash in a list context and assuming it yields key-value pairs can silently produce an alternating sequence instead.

7. Recheck shell and language assumptions

Shell syntax is not Perl syntax. Script arguments are in @ARGV, not $1 and $2. String tests use eq and ne, while numeric tests use == and !=. Perl also compiles the complete program before running it, apart from BEGIN blocks, so a late syntax error prevents normal execution.

$ perl -e 'print "first argument: $ARGV[0]\n"' example-value
first argument: example-value

Do not assume that backticks behave like the shell that launched the script. The manual documents interpolation and return-value differences. If a script constructs a command from external input, stop for a separate security review before changing it. Testing syntax is not the same as making command execution safe.

8. Finish with a repeatable review

Run the local guide again after fixing the obvious traps, then compile the complete script and test it with representative input. Keep the original input and output paths unchanged during this review. No elevated privileges are needed for any command shown here.

$ man perltrap
$ perl -c example.pl
example.pl syntax OK
$ printf 'one\ntwo\n' | perl example.pl
one
two

If the script reads files, add a harmless test fixture rather than pointing the first run at production data. If it writes files, use a temporary directory and check the output before replacing anything. The guide identifies traps; it cannot prove that application logic, permissions or external commands are correct.

Done means

  • perltrap(1) was read from the installed perl-doc package.
  • The script starts with use strict and use warnings, where compatible with its design.
  • String, numeric and matching operators were checked deliberately.
  • Input loops, $_, @ARGV, context, indexes and scopes were reviewed.
  • perl -c reports syntax OK before the representative test run.