Skip to main content

You are here

Perl

Perl - Remove all blank lines from a file

Remove all blank lines from a file using Perl:

perl -ne 'print unless /^\s+$/ ' test.txt

Programming: 

Can't locate Time/HiRes.pm CPAN error on CentOS 7

So the default Perl installation that ships with CentOS 7 minimal install does not include Time::HiRes, which is necessary if you want to use CPAN.

Error:

Can't locate Time/HiRes.pm in @INC (@INC contains: /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 /root) at /usr/share/perl5/Net/Ping.pm line 313.

Fix:

yum install perl-Time-HiRes

Programming: 

Linux: 

Monitoring TFTPd server

So I just spent the last two hours of my life trying to figure why PXE booting was not working in my home network. Turned out the root cause was my fault completely since, I forgot to add a firewall rule on my dhcp/PXE server to allow incoming UDP connections on port 69.

Fix:

iptables -A INPUT -p udp -m udp --dport 69 -j ACCEPT

As with just about any other service, this service can be monitored using Nagios. Originally, I had problems using the check_tftp.pl and check_tftp plugins that are available from on Nagios Exchange repo, mainly because of the way I have setup my machines.

check_tftp This plugin was useless in my environment because this plugin all it does is send out an status command to the TFTP server. Since I'm using the BSD tftp client, all status commands sent to any host will always show up as being connected regardless.
http://exchange.nagios.org/directory/Plugins/Network-Protocols/TFTP/chec...

check_tftp.pl This plugin was not opted to work in my environment. Mainly because it uses Net::TFTP, unlike the tftp client application, Net::TFTP does not support specifying a custom reverse connection port (or port ranges). By default, when connecting to a TFTP server, the TFTP server will dynamically choose a random non-standard port to connect back to the client machine and proceed with the TFTP download. My Nagios machine (like all of my machines) are set to drop all incoming packets except for specific ports and related/established connections.
http://exchange.nagios.org/directory/Plugins/Network-Protocols/TFTP/chec...

I wrote a simple Nagios plugin that monitors TFTP. All it simply does, is download a non-empty file called test.txt.

#!/usr/bin/perl -w

# Tony Baltazar. root[@]rubyninja.org

use strict;
use Getopt::Long;




my %options;
GetOptions(\%options, "host|H:s", "port|p:i", "rport|R:s", "file|f:s", "help");


if ($options{help}) {
	usage();
	exit 0;
} elsif ($options{host} && $options{port} && $options{file}) {
	chdir('/tmp');

	my $cmd_str = ( $options{rport} ?  "/usr/bin/tftp -R $options{rport}:$options{rport} $options{host} $options{port} -c get $options{file}" : "/usr/bin/tftp $options{host} $options{port} -c get $options{file}");

	my $cmd = `$cmd_str`;
	if ($? != 0) {
		print "CRITICAL: $cmd";
		system("rm -f /tmp/$options{file}");
		exit 2;
	} else {
		if (! -z "/tmp/$options{file}" ) {
			print "TFTP is ok.\n$cmd";
			system("rm -f /tmp/$options{file}");
			exit 0;
		} else {
			print "WARNING: $cmd";
			system("rm -f /tmp/$options{file}");
			exit 1;
		}
	}

} else {
	usage();
}



sub usage {
print < --port= --file=]

   --host | -H  : TFTP server.
   --port | -p  : TFTP Port.
   --file | -m  : Test file that will be downloaded.
   --help | -h  : This help message.

Optionally,
   --rport | -R : Explicitly force the reverse originating connection's port.

EOF
}

https://github.com/alpha01/SysAdmin-Scripts/blob/master/nagios-plugins/c...

Seeing the plugin in action:
Assuming, we're using port udp 1069 to allow the TFTP server (192.168.1.2) to connect to the Nagios monitoring machine.

[[email protected] libexec]# iptables -L -n |grep "Chain INPUT"
Chain INPUT (policy DROP)
[[email protected] libexec]# iptables-save|grep 1069
-A INPUT -s 192.168.1.2/32 -p udp -m udp --dport 1069 -j ACCEPT

Firewall not allowing TFTP to connect back using port 1066.

[[email protected] libexec]# su - nagios -c '/usr/local/nagios/libexec/check_tftp.pl -H 192.168.1.2 -p 69 -R 1066 -f test.txt'
CRITICAL: Transfer timed out.

Downloading a non-existing file from the TFTP server.

[[email protected] tmp]# su - nagios -c '/usr/local/nagios/libexec/check_tftp.pl -H 192.168.1.2 -p 69 -R 1069 -f test.txtFAKESHIT'
WARNING: Error code 1: File not found

Successful connection and transfer.

[[email protected] tmp]# su - nagios -c '/usr/local/nagios/libexec/check_tftp.pl -H 192.168.1.2 -p 69 -R 1069 -f test.txt'
TFTP is ok.

Programming: 

Awesome Applications: 

Can't locate local/lib.pm CPAN error on Ubuntu 12.04

So the default Perl installation that ships with Ubuntu 12.04 LTS, does not include local::lib which is necessary if you want to use CPAN.

Error:

Can't locate local/lib.pm in @INC (@INC contains: /home/tony/perl5/lib/perl5 /etc/perl /usr/local/lib/perl/5.14.2 /usr/local/share/perl/5.14.2 /usr/lib/perl5 /usr/share/perl5 /usr/lib/perl/5.14 /usr/share/perl/5.14 /usr/local/lib/site_perl /home/tony) at /usr/share/perl/5.14/CPAN/FirstTime.pm line 1300.

Fix:

sudo apt-get install liblocal-lib-perl

Reference: http://stackoverflow.com/questions/16702642/cant-locate-local-lib-pm-in-...

Programming: 

Linux: 

ZFS on Linux: Nagios check_zfs plugin

To monitor my ZFS pool, of course I'm using Nagios, duh. Nagios Exchange provide a check_zfs plugin written in Perl. http://exchange.nagios.org/directory/Plugins/Operating-Systems/Solaris/c...

Although the plugin was originally designed for Solaris and FreeBSD systems, I got it to work under my Linux system with very little modification. The code can be found on my SysAdmin-Scripts git repo on GitHub https://github.com/alpha01/SysAdmin-Scripts/blob/master/nagios-plugins/c...

[[email protected] ~]# su - nagios -c "/usr/local/nagios/libexec/check_zfs backups 3"
OK ZPOOL backups : ONLINE {Size:464G Used:11.1G Avail:453G Cap:2%}

Programming: 

Awesome Applications: 

Monitoring computer's temperature with lm_sensors

One of the primary reasons I use SSD drives on both of my Mac Minis that I use as hypervisors (besides speed), is that compared to regular hard drives, SSD drives consume far less power and more importantly generate less heat. Before using SSD drives on my machines, the fan noise both of them made during the middle of summer was pretty evident compared to any other time during the year.

Although at the time I did little research about proactively monitoring the temperature of my machines, now thanks to the Nagios book that I'm currently reading, I learned about the tool lm-sensors, which is available to monitor the hardware temperature in Linux.

Installing lm-sersors in Ubuntu Server 12.04 is really simple.

sudo apt-get install libsensors4 libsensors4-dev lm-sensors

Since lm-sensors requires low-level hooks to monitor hardware temperate, it comes with the utility sensors-detect, which can be used to automatically detect and load the appropriate kernel modules for the lm-sensors tool to function on the respective piece of hardware.

[email protected]:~$ sudo sensors-detect
# sensors-detect revision 5984 (2011-07-10 21:22:53 +0200)
# System: Apple Inc. Macmini5,1
# Board: Apple Inc. Mac-8ED6AF5B48C039E1

This program will help you determine which kernel modules you need
to load to use lm_sensors most effectively. It is generally safe
and recommended to accept the default answers to all questions,
unless you know what you're doing.

Some south bridges, CPUs or memory controllers contain embedded sensors.
Do you want to scan for them? This is totally safe. (YES/no): YES
[...]

In the case of my mid 2011 Apple Mac Minis, it was only able to use the coretemp module. File /etc/modules :

# Generated by sensors-detect on Sat Feb  2 21:22:20 2013
# Chip drivers
coretemp

After the module has been added, then its just a matter of loading the recently applied modules.

[....]
Do you want to add these lines automatically to /etc/modules? (yes/NO)yes
Successful!

Monitoring programs won't work until the needed modules are
loaded. You may want to run 'service module-init-tools start'
to load them.

Unloading i2c-dev... OK
Unloading i2c-i801... OK
Unloading cpuid... OK

[email protected]:~$ sudo service module-init-tools start
module-init-tools stop/waiting
[email protected]:~$

Now that the appropiate kernel modules have been loaded. I have everything needed to check the temperature.

[email protected]:~$ sensors
coretemp-isa-0000
Adapter: ISA adapter
Physical id 0: +49.0°C (high = +86.0°C, crit = +100.0°C)
Core 0: +48.0°C (high = +86.0°C, crit = +100.0°C)
Core 1: +50.0°C (high = +86.0°C, crit = +100.0°C)

applesmc-isa-0300
Adapter: ISA adapter
Exhaust : 1801 RPM (min = 1800 RPM)
TA0P: +36.0°C
TA0p: +36.0°C
TA1P: +34.8°C
TA1p: +34.8°C
TC0C: +47.0°C
TC0D: +44.8°C
TC0E: +57.5°C
TC0F: +58.5°C
TC0G: +94.0°C
TC0J: +0.8°C
TC0P: +42.5°C
TC0c: +47.0°C
TC0d: +44.8°C
TC0p: +42.5°C
TC1C: +50.0°C
TC1c: +50.0°C
TCFC: +0.2°C
TCGC: +49.0°C
TCGc: +49.0°C
TCPG: +98.0°C
TCSC: +50.0°C
TCSc: +50.0°C
TCTD: +255.5°C
TCXC: +49.5°C

Of course, I just had to write a Nagios plugin to monitor them:

#!/usr/bin/env perl
use strict;
# Tony Baltazar. root[@]rubyninja.org

use constant OK => 0;
use constant WARNING => 1;
use constant CRITICAL => 2;
use constant UNKNOWN => 3;

my %THRESHOLDS = (OK => 70, WARNING => 75, CRITICAL => 86);

# Sample output
#Physical id 0:  +55.0°C  (high = +86.0°C, crit = +100.0°C)
#Core 0:         +54.0°C  (high = +86.0°C, crit = +100.0°C)
#Core 1:         +55.0°C  (high = +86.0°C, crit = +100.0°C)
my @get_current_heat = split "\n", `sensors 2>/dev/null|grep -E -e '(Physical id 0|Core [0-1])'`;


my $counter = 0;
my $output_string;

for my $heat_usage_per_core (@get_current_heat) {
	$heat_usage_per_core =~ /(.*):\s+\+([0-9]{1,3})/;
	my $core = $1;
	my $temp = $2;
	
	
	if ($temp < $THRESHOLDS{OK}) {
		$output_string .= "$core - temperature : $temp" . 'C | ';
		$counter++;
	} elsif ( ($temp > $THRESHOLDS{OK}) && ($temp >= $THRESHOLDS{WARNING}) && ($temp < $THRESHOLDS{CRITICAL}) ) {
		print "WARNING! $core temperature: $temp\n";
		exit(WARNING);
	} elsif ( ($temp > $THRESHOLDS{OK}) && ($temp > $THRESHOLDS{WARNING}) && ($temp >= $THRESHOLDS{CRITICAL}) ) { 
		print "CRITICAL! $core temperature: $temp\n";
		exit(CRITICAL);
	}
}

if ($counter == 3 ) {
	print $output_string;
	exit(OK);
} else {
	print "Unable to get all CPU's temperature.\n";
	exit(UNKNOWN);
}

Programming: 

Linux: 

Awesome Applications: 

Learning Perl, 5th Edition

I finally finished reading my second book on Perl. Unlike Apress’ Beginning Perl, Learning Perl 5th Edition by Randal Schwartz, Tom Phoenix, and brian d foy is not a book for someone new to programming.
With a solid understanding of dynamic languages like PHP and Ruby, I found most of the material covered on this book very comprehensive, thus said, at times I found myself re-reading portions of the chapters just to understand concept the authors were trying to cover.
For the most part, I read this book jointly with Apress’ Beginning Perl and I found this book to have more practical real word code examples (at least if you’re a sysadmin). The most notably difference on how this book was written for someone who is new to programming with Perl, but to not new to programming are the three chapters the authors dedicate to regular expressions.

Chapter 1: Introduction
Chapter 2: Scalar Data
Chapter 3: Lists and Arrays
Chapter 4: Subroutines
Chapter 5: Input and Output
Chapter 6: Hashes
Chapter 7: In the World of Regular Expressions
Chapter 8: Matching with Regular Expressions
Chapter 9: Processing Text with Regular Expressions
Chapter 10: More Control Structures
Chapter 11: Perl Modules
Chapter 12: File Tests
Chapter 13: Directory Operations
Chapter 14: Strings and Sorting
Chapter 15: Smart Matching and given-when
Chapter 16: Process Management
Chapter 17: Some Advanced Perl Techniques
Chapter 14 Introduction to CGI
Chapter 15: Perl and DBI

I would only suggest this book to someone with a solid knowledge of another scripting language. As Randal Schwartz commented on my original book review in my blog, "if you know why you would want an array, and what a subroutine is for, you’ll probably do ok."

Rating: 3/5
Learning Perl, 5th Edition

Book: 

Scripting Language: 

Beginning Perl

It only took me exactly two years to read the Apress book Beginning Perl by James Lee, and I would have to admit this is the best programming book that I’ve read so far. I would need to give this book high praise as it was easy and fun to read ( pretty much taught me programming in Perl. Even tough I don’t use Perl on a daily bases, nor is Perl my prefer language of choice to write scripts ) but thanks to this book I could confidently read other programmers perl code and have an understanding on what’s going on in their program.

Chapter 1: First Steps in Perl
Chapter 2: Scalars
Chapter 3: Control Flow Constructs
Chapter 4: Lists and Arrays
Chapter 5: Hashes
Chapter 6: Subroutines/Functions
Chapter 7: Regular Expressions
Chapter 8: Files and Data
Chapter 9: String Processing
Chapter 10: Interface to the Operating System
Chapter 11: References
Chapter 12: Object-Oriented Perl
Chapter 13: Modules
Chapter 14 Introduction to CGI
Chapter 15: Perl and DBI

I would highly recommended this book to anybody starting or wanting to learn Perl.

Rating: 5/5
Beginning Perl, Second Edition

Book: 

Scripting Language: 

Premium Drupal Themes by Adaptivethemes