131

I have seen lots of ways of running Perl code or scripts, with different flags. However, when I try to google for what each flag means, I mainly get results to generic Perl sites and no specific information regarding the flags or their use is found there.

Below are the flags that I encounter most often, and I don't have a clue what they mean:

  • perl -pe
  • perl -pi
  • perl -p
  • perl -w
  • perl -d
  • perl -i
  • perl -t

I will be very grateful if you tell me what each of those mean and some use cases for them, or at least tell me a way of finding out their meaning.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Tudor Constantin
  • 26,330
  • 7
  • 49
  • 72
  • 26
    googling for basic answers about perl will often lead you to some really unhelpful sites. always check perl's own documentation first. – ysth Jun 10 '11 at 05:09
  • 3
    Seconded. In this case, `perldoc perlrun` has a list of all the command-line options Perl accepts. – Sherm Pendley Jun 13 '11 at 00:28
  • 1
    [Useful guide to some of Perl's command line options](http://www.perl.com/pub/2004/08/09/commandline.html) over on perl.com. – Dave Cross Jun 10 '11 at 09:50
  • 6
    Google problem: The minus sign is interpreted by Google as meaning "exclude this term." To avoid this behavior place the term containing the minus sign in quotes. – Roger Krueger Dec 12 '17 at 14:25

4 Answers4

179

Yes, Google is notoriously difficult for looking up punctuation and, unfortunately, Perl does seem to be mostly made up of punctuation :-)

The command line switches are all detailed in perlrun (available from the command line by calling perldoc perlrun). Going into the options briefly, one-by-one:

  • -p: Places a printing loop around your command so that it acts on each line of standard input. Used mostly so Perl can beat the pants off Awk in terms of power AND simplicity :-)
  • -n: Places a non-printing loop around your command.
  • -e: Allows you to provide the program as an argument rather than in a file. You don't want to have to create a script file for every little Perl one-liner.
  • -i: Modifies your input file in-place (making a backup of the original). Handy to modify files without the {copy, delete-original, rename} process.
  • -w: Activates some warnings. Any good Perl coder will use this.
  • -d: Runs under the Perl debugger. For debugging your Perl code, obviously.
  • -t: Treats certain "tainted" (dubious) code as warnings (proper taint mode will error on this dubious code). Used to beef up Perl security, especially when running code for other users, such as setuid scripts or web stuff.
paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
  • 1
    I did not notice that you referred to `perldoc perlrun`. I have deleted my answer. :-) – Alan Haggai Alavi Jun 10 '11 at 04:48
  • Thank you for your enlighting response – Tudor Constantin Jun 10 '11 at 04:56
  • 4
    `-w` is generally to be avoided, actually, as it enables warnings for **all** code, including CPAN modules which weren't written with warnings in mind. The results are generally pretty noisy, as well as pretty useless. –  Jun 10 '11 at 05:28
  • 10
    `-w` is generally avoided, but it should be replaced with `use warnings` in your own code. – plusplus Jun 10 '11 at 08:57
  • 7
    @duskwuff: In general I agree, and I do `use warnings` in my own code, but -w does have a use - it helps weed out poorly-written CPAN modules. :-) – Sherm Pendley Jun 13 '11 at 00:30
  • Can you enlighten about the order of the flags? If I do `perl -i -0pe` everything works as expected, if I do `perl -i -0ep` it doesn't, if I change other flags order, it also breaks. What's the deal with that? I'm very confused… – Ian Bytchek Nov 26 '14 at 13:11
  • 3
    @IanBytchek Arguments that may/must take an additional parameter can't be inside a compressed list. `-i` takes an extension for the backup. `-e` takes a perl command. In `-0ep` you are telling perl that 'p' is a perl command instead of an argument. That won't work out well at all. – tjd May 23 '16 at 13:16
13

The -p flag basically runs the script with

while (<>) {
# exec here
}
continue {
    print or die "-p destination: $!\n";
}

-e allows you to pass a script to as a parameter rather than as a file:

perl -e '$x = "Hello world!\n"; print $x;'

-i directs the interpreter that all data passed to STDIN by the executing script is to be done inplace.

-w is the same as use warnings;, but in a global rather than local scope

-d runs the Perl debugger

lmat - Reinstate Monica
  • 7,289
  • 6
  • 48
  • 62
zellio
  • 31,308
  • 1
  • 42
  • 61
  • 2
    `-w` is not quite the same as `use warnings`, the latter is scoped to the local file – plusplus Jun 10 '11 at 09:07
  • plusplus, true, patching answer. – zellio Jun 10 '11 at 13:22
  • 2
    Passing the script as an argument is not the same as passing it on STDIN. -i takes file names from the argument list, not stdin. While STDIN is often associated with the controlling terminal, and is inherited from the shell that reads stdin and sets up the argument list to perl, they are NOT the same thing. – William Pursell Jun 10 '11 at 15:57
8

Other have mentioned perlrun. If you use B::Deparse, you can see what it means (for most things):

$ perl -MO=Deparse   -p  -e 1
LINE: while (defined($_ = <ARGV>)) {
    '???';
}
continue {
    die "-p destination: $!\n" unless print $_;
}
-e syntax OK

1 is represented by '???', because it is optimized away.

$ perl -MO=Deparse   -p -i  -e 1
BEGIN { $^I = ""; }
LINE: while (defined($_ = <ARGV>)) {
    '???';
}
continue {
    die "-p destination: $!\n" unless print $_;
}
-e syntax OK

-i sets $^I, like

$ perl -MO=Deparse   -p -i.bak  -e 1
BEGIN { $^I = ".bak"; }
LINE: while (defined($_ = <ARGV>)) {
    '???';
}
continue {
    die "-p destination: $!\n" unless print $_;
}
-e syntax OK

But remember, <ARGV> uses 2-argument open, so don't have filenames that start with > < or start/end with |.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
liame
  • 91
  • 2
5

There is also one important flag -n which is not mentioned in the list.

-n works the same as -p, only it does not print $_ by default. This can be very useful in filtering text files.

In this way Perl can replace grep | sed in a single one-liner.

For example:

perl -ne 'print "$1\n" if /Messages read: (\d+)/' <my_input.txt

Will print out every integer value found after "Messages read: ", and nothing more.

rustyx
  • 80,671
  • 25
  • 200
  • 267