Home / Alt manpages / perlrun(1)

  • perlrun(1)
  • User command
  • linux

Run Perl One-Liners and Scripts Safely from the Shell

You will use perl to run a script, test its syntax, process text one line at a time, and inspect the interpreter selected by your shell. The examples match Perl 5.38.2 on this machine, as documented by the installed perlrun manual page. Allow 15 minutes for the first pass.

You need a shell, a readable input file for the processing examples, and the perl package. No command in this guide needs elevated privileges. Work in a disposable directory if you are testing a script that writes files.

1. Confirm which Perl will run

Start by checking the executable and version. This catches a common distraction: a script may be using a different Perl from the one you expected because PATH selects the first match.

$ command -v perl
/usr/bin/perl
$ perl -v
This is perl 5, version 38, subversion 2 (v5.38.2) built for x86_64-linux-gnu-thread-multi

The exact build line can vary between installations. For a script that depends on a particular release, use a specific interpreter path or declare a minimum version in the program with use v5.38;. The -V switch gives configuration details and the current module search path:

$ perl -V:version
version='5.38.2';
$ perl -V:archname
archname='x86_64-linux-gnu-thread-multi';

2. Run a script or a small command

Pass a filename when the program is in a file. Perl compiles the complete program before executing it, so a syntax error does not leave a partly run script.

$ perl /path/to/script.pl

For a short task, -e supplies the program on the command line. Unix shells use single quotes here so the shell does not expand Perl variables or interpret Perl punctuation:

$ perl -e 'print "hello from Perl\n"'
hello from Perl

Perl also accepts several -e switches, but each part still needs normal Perl separators such as semicolons. -E behaves like -e while enabling optional language features in the main compilation unit. If an argument begins with a hyphen and must be treated as a filename, put -- before it; options stop there.

3. Check syntax without running the main program

Use -c before handing a script to someone else or placing it in a scheduled job. It checks syntax and exits without running the normal program body:

$ perl -c /path/to/script.pl
/path/to/script.pl syntax OK

This is a compile check, not a completely inert sandbox. Perl still runs BEGIN, UNITCHECK, CHECK, and use statements. Do not use -c as permission to check an untrusted script on a sensitive machine.

4. Process input with the implicit loop

The -n switch wraps your code in a loop over the files named after the program. It reads records but does not print them. -p uses the same idea and prints each record after your code changes it. These modes are useful for short, reviewable transformations.

$ printf 'alpha\nbeta\n' | perl -nle 'print uc'
ALPHA
BETA
$ printf 'alpha\nbeta\n' | perl -ple 's/^/item: /'
item: alpha
item: beta

-l removes the input line ending and adds a line ending back to output. It is convenient for line-oriented examples, but it changes the record and output separators. Without -p, output is your responsibility. A missing input file is reported as a warning and Perl moves on to another file, so check the exit status and diagnostics when processing a batch.

For records that may contain newlines, do not use the ordinary line loop blindly. -0 changes the input record separator, and -0 with no digits selects the null character. For whole-file reads, -g is the simpler alias for -0777. Null-delimited input avoids treating a newline inside a pathname as the end of that pathname:

$ find /path/to/data -type f -print0 | perl -n0e 'print "$ARGV\n"'
/path/to/data/example one.txt

Use the exact delimiter required by the producer. A line-oriented command is not automatically safe for arbitrary filenames.

5. Treat in-place editing as a file change

-i redirects the output of the implicit input loop back to each input filename. This changes files, and the no-extension form can remove the original name before the replacement is complete. Do not start with it against valuable data.

For a controlled test, make a temporary copy and request a backup extension:

$ cp -- /path/to/input.txt /tmp/input.txt.test
$ perl -pi.bak -e 's/OLD/NEW/g' /tmp/input.txt.test
$ sed -n '1,5p' /tmp/input.txt.test
$ sed -n '1,5p' /tmp/input.txt.test.bak

The first file contains the transformed text and the .bak file contains the original. Compare both before replacing the real input. If the result is wrong, restore it explicitly:

$ cp -- /tmp/input.txt.test.bak /tmp/input.txt.test

The backup is created even when no line changes. After you have verified the replacement, remove only the known backup path if you no longer need it. That deletion is irreversible, so keep the backup during review.

6. Make scripts predictable

A Unix script normally begins with a shebang such as #!/usr/bin/perl or #!/usr/bin/env perl. The first form names an exact installation; the second chooses whichever perl appears first in PATH. Use the exact path when the interpreter version matters, and make the file executable only when direct invocation is part of the interface:

$ chmod u+x /path/to/script.pl
$ /path/to/script.pl

Keep command-line switches visible and short. Perl can read options from PERL5OPT, and library search paths can also come from PERL5LIB. Those environment variables affect every Perl command in that shell, so inspect them when a module appears to come from the wrong directory:

$ env | grep -E '^(PERL5LIB|PERL5OPT)='
$ perl -V

For a one-off dependency directory, prefer an explicit -I/path/to/lib or a use lib statement you can see in the command or source. With taint checking, PERL5LIB and PERLLIB are ignored.

7. Know the security switches

Use -T to enable taint checks for code handling input from people you do not trust, such as a network-facing service. Taint mode must be selected early. -t only turns taint failures into warnings and is a temporary development aid, not a production substitute.

Do not add -U casually. It permits unsafe operations, including directory unlinking as superuser and setuid execution with fatal taint checks weakened to warnings. Debugging switches such as -d can load debugger code, while -M loads a module and invokes its import method. Treat both as code execution, especially when values came from an untrusted command line or environment.

Done means

  • You confirmed the interpreter path and version with command -v perl and perl -v.
  • You can choose between a script file, -e, standard input, and the explicit - filename.
  • You used -c for a syntax check and understand that compile-time code can still run.
  • You know whether -n or -p prints records, and when -0 or -g is needed.
  • You tested -i on a copy with a backup and have a recovery command.
  • You reviewed PATH, PERL5LIB, and PERL5OPT when behaviour does not match the command.