PERL - Tips & snippets

mail

Perl CLI flags

-d
Runs under the Perl debugger. For debugging your Perl code, obviously.
-e
execute the program given 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.
-n
Places a non-printing loop around your command.
-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 :-)
-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.
-w
Activates some warnings. Any good Perl coder will use this.
mail

PERL's // and //= operators

// :

  • expression1 // expression2
    returns the value of expression1 if it's defined, otherwise, the value of expression2
  • equivalent to :
    defined(expression1) ? expression1 : expression2
  • This is very useful for providing default values for variables.

//= :

  • //= is the assignment operator version of //
  • $i //= '08';
    is a shorthand for :
    $i = (defined $i) ? $i : '08';

Check for support :

The // and //= appeared with Perl 5.10.0. To quickly check whether they are supported, try these :
  • perl -e 'my $i = $undefinedVariable // 2; print $i;'
  • perl -e 'my $i //= 2; print $i;'
Both should return : 2.
mail

PERL variables

This article may sound like "stating the obvious" (which is not completely wrong). However, since :
  • it's been ages I've not written PERL
  • similar stuff in different languages have different names
  • in PERL, a single $, %, @ or & changes the meaning of things
  • Nothing is ever obvious for everybody.
... better stating the obvious rather than writing buggy code
Notation Variable type Details
$myVariable scalar
@myVariable array aka list in Python. Items are referenced by their (0-indexed) position in the array.
%myVariable hash aka associative array or "key-value" pairs (details)
mail

CPAN libraries

Stop f**king around with CPAN while installing libs (source) :

cpanminus (aka App::cpanminus) is a script to get, unpack, build and install modules from CPAN and does nothing else. It's dependency free (can bootstrap itself), requires zero configuration, and stands alone. When running, it requires only 10MB of RAM.
To install it (as root) :

  1. apt install curl make
  2. curl -L http://cpanmin.us | perl - App::cpanminus
    --> Working on App::cpanminus
    Fetching http://www.cpan.org/authors/id/M/MI/MIYAGAWA/App-cpanminus-1.7044.tar.gz ... OK
    Configuring App-cpanminus-1.7044 ... OK
    Building and testing App-cpanminus-1.7044 ... OK
    Successfully installed App-cpanminus-1.7044
    1 distribution installed
  3. From then on, install modules by executing (as root if necessary) :
    • cpanm Foo::Bar
    • cpanm Nagios::Plugin::WWW::Mechanize
    • cpanm git://github.com/perldork/Nenm--Utils.git
    • OR (if tests fail) : cpanm -n Foo::Bar
      -n means --notest
  4. Enjoy !
Nenm::Utils : download from https://github.com/perldork/Nenm--Utils, then copy it in the PERL libs tree (/usr/local/lib/perl/5.10.1/Nenm/Utils.pm)

Install a library (Net::DNS) on Windows :

  • normal install : just open a system shell and run : cpan Net::DNS
  • force install :
    1. open a system shell
    2. perl -MCPAN -e shell
    3. force install Time::HiRes
    4. exit
  • checking install :
    • from the system shell : cpan Time::HiRes, which should output :
      xxx is up to date
    • OR from the CPAN shell (perl -MCPAN -e shell) : i / Time::HiRes
mail

PERL cryptic special variables

Variable Name Usage Details
Error management
$@ error code / message detected by the PERL interpreter The variables $@, $!, $^E and $? contain information about different types of error conditions that may appear during execution of a Perl program. The variables are shown ordered by the "distance" between the subsystem which reported the error and the Perl process. (source)
$! error code / message detected by the C library
$^E error code / message detected by the operating system
$? error code / message detected by an external program
Other stuff
$#myArray index of the last element of the array myArray Since Perl arrays start at element 0, this number will be one less than the length of the array.
$& the string that was matched by the last successful pattern match
$/ the input record separator. defaults to \n
$_ each element of LIST, alias to the list value
$_[n] the nth argument passed to the subroutine starts at 0
@_ array containing all the arguments sent to a subroutine
  • To load arguments passed to a subroutine with : mySubRoutine('foo','bar','baz');
    Do in subroutine : my ($arg1, $arg2, $arg3)=@_;
    Or use $_[n], being the nth argument passed to the subroutine (starting at 0)
  • my(@args)=@_; is used mainly when the argument is a list of data to process.
  • If a single argument is sent to the sub, it's more convenient to use shift :
    $result=mySub($foo);
    sub mySub {
    	my $myVariable=shift;
    	...
    	}
mail

structures

mail

hashes

2 ways to declare/use hashes :

#!/usr/bin/perl -w
use strict;

my $key;
my $value;

my $hashTable = { name => 'Jeff', age => 23 };			$-named, data between curly brackets
foreach $key (keys %$hashTable) {
	$value = $hashTable->{$key};				de-referenced with the -> operator
	print "$key :\t$value\n";
	}

print "\n";

my %hashTable2 = ( firstname => 'Bob', how_old => 22 );	%-named, data between parenthesis
foreach $key (keys %hashTable2) {
	$value = $hashTable2{$key};				no de-reference operator needed
	print "$key :\t$value\n";
	}
age :	23
name :	Jeff

firstname :	Bob
how_old :	22
Details on Dereferencing.

hash of (anonymous) hashes (source) :

my %config = (
	objects		=> {...},
	commands	=> {...},
	misc		=> {...},
	);



foreach my $topic (keys %config) {	# parse the indices of '%config'. the current index at each iteration is stored into $topic
	print '$topic : '.$topic.EOL;
	# since we're parsing a hash of hashes, $config{$topic} is a hash itself (casted to use the 'keys' function)
	foreach my $data (keys %{$config{$topic}}) {
		print '$data : '.$config{$topic}{$data}.EOL;
		}
	}
print $config{'hosts'}{'outputFile'};