Hello, fellow sysadmins and Perl enthusiasts! Today, I'm excited to share my first Perl-related post, showcasing a template I've crafted for my day-to-day work as a Debian Linux system administrator. This template is designed to handle what I need fast: quick parsing, system daemon installer scripts, and other admin tasks that require rapid development without sacrificing robustness. Let's dive into the structure and functionality of this template, and I'll explain why I made these choices.
You can find more of my Perl scripts and one-liners at https://github.com/16BitMiker. These will give you a sense of my style and the kinds of tasks I tackle regularly.
First, let's look at the complete template:
xxxxxxxxxx
#!/usr/bin/env perl
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ About
#
# Perl Template
# by: 16BitMiker
# v2024-11-12
#
# //
# _oo\
# (__/ \ _ _
# \ \/ \/ \
# ( )\
# \_______/ \
# [[] [[]
# [[] [[]
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Pragmas
use ;
use ;
use ;
use ;
use open qw(:std :utf8);
use :: qw(:constants);
use qw(say state);
use qw($RealBin);
use :: ;
use :: ;
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Config
# Configure Data::Dumper
$Data:::: = 1; # Produce output that's valid as Perl code
$Data:::: = 1; # Turn on pretty-printing with a single-space indent
$Data:::: = 1; # Sort hash keys for consistent output
$Data:::: = 1; # Avoid outputting variable names (just the structure)
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Vars
my $db = {};
my $dt = {
=> \&msg,
=> \&run,
=> \&bye,
=> \&clear,
=> \&border,
=> \&sleepyTime,
};
$|++;
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Init
# Code goes here!
{
$dt->{zzz}(3);
}
{
| : $_|, ||); (
};
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Subs
sub #ypewriter
{
my $text = shift;
# Use regex to process each character of the text
$text =~ `.`
select(undef, undef, undef, rand(0.05)); # Small random delay
print $&; # Print the matched character
`sger;
}
sub msg
{
chomp( my $msg = shift );
chomp( my $color = shift // q|GREEN| );
print q|> |;
eval qq`print ${color} ||`;
t( $msg );
say RESET q||;
}
sub border
{
my $num = shift // 42;
say q|-|x$num;
}
sub clear
{
# Clear the screen
print "\033[2J"; # This clears the entire screen
print "\033[H"; # This moves the cursor to the top-left corner
}
sub sleepyTime
{
my $random = shift // 0;
my $fixed = shift // 0;
# Early return if both random and fixed times are too small
return 0 if ( $random <= 2 and $fixed == 0 );
# Calculate sleep time and display it
my $sleep = int( rand( $random ) ) + $fixed;
say qq|> |, q|Sleeping for |, YELLOW UNDERLINE $sleep, RESET q| seconds...|;
sleep $sleep;
}
sub run
{
my $key = shift;
try
{
my ($cmd) = values %{$$db[$key]};
msg( $cmd );
system $cmd;
die qq|Command failed with exit code $?| if $?;
}
catch
{
msg( qq|Command failed: $_|, q|RED| );
bye();
};
}
sub bye
{
msg( q|Bye bye!|, q|RED| );
exit 69
}
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ End
__END__
Now, let's break down the key components and dive into why I made these choices, keeping in mind my needs as a Debian sysadmin.
I start with essential pragmas: strict, warnings, and autodie. These are crucial for catching errors early, which is vital when you're writing scripts that interact with system components. autodie is particularly useful for sysadmin tasks as it automatically dies if system calls fail, saving me from manual error checking.
The utf8 pragma and open directive ensure proper handling of UTF-8, which is essential when dealing with log files or system outputs that might contain non-ASCII characters.
I've included some powerful modules:
Term::ANSIColor: For colorful console output, making it easier to quickly parse information visually.
feature qw(say state): Enables modern Perl features for cleaner syntax.
FindBin: Helps locate the script's directory, useful for relative path operations in installer scripts.
Data::Dumper: Invaluable for debugging complex data structures.
Try::Tiny: Provides more robust exception handling than eval, crucial for system scripts where failures need to be caught and handled gracefully.
I've configured Data::Dumper to produce more useful output:
xxxxxxxxxx
$Data:::: = 1;
$Data:::: = 1;
$Data:::: = 1;
$Data:::: = 1;
These settings ensure that dumped data is valid Perl code, nicely indented, with sorted hash keys, and without extraneous variable names. This configuration makes debugging output more readable, which is crucial when you're trying to quickly diagnose issues in a system script.
I've defined two hashes:
$db: An empty hash for storing data. This provides a flexible structure for various uses, like storing configuration or temporary data.
$dt: A hash of references to utility functions.
The $dt hash is particularly useful. It provides quick access to commonly used functions through short keys. This design choice allows for more concise code when calling these functions throughout the script, speeding up development and improving readability.
The initialization section is wrapped in a try-catch block:
xxxxxxxxxx
{
$dt->{zzz}(3);
}
{
| : $_|, ||); (
};
This demonstrates proper error handling right from the start, which is crucial for system scripts that need to be robust and fail-safe.
I've included several utility functions that cater to common sysadmin needs:
t (typewriter): Creates a typewriter effect when printing text. While it might seem decorative, it's actually useful for creating user-friendly installers or for throttling output in scripts that might otherwise scroll too quickly.
msg: Prints colorful messages. This is incredibly useful for making important information stand out in console output, especially when parsing logs or displaying system status.
border: Prints a horizontal border. Simple, but effective for creating clear visual separations in console output.
clear: Clears the console screen. Essential for creating clean, professional-looking interfaces for interactive scripts.
sleepyTime: Introduces a random or fixed delay. This can be crucial for scripts that need to wait for system processes to complete or for throttling operations to prevent overload.
run: Executes system commands with error handling. This is perhaps the most important function for sysadmin scripts, as it provides a safe way to run system commands and handle potential errors.
bye: Exits the script with a farewell message. The non-standard exit code (69) is a personal touch that adds a bit of personality to my scripts.
This template represents my approach to creating quick, effective Perl scripts for system administration tasks. It incorporates robust error handling, flexible data structures, and utility functions that cater specifically to the needs of a Debian Linux sysadmin.
By using this template, I can quickly spin up scripts for parsing logs, installing daemons, or performing other system tasks without having to recreate the same boilerplate code each time. The colorized output and user-friendly functions like the typewriter effect allow me to create scripts that are not only functional but also provide clear, visually appealing feedback.
The template's structure aligns well with the style of scripts you'll find in my GitHub repository (https://github.com/16BitMiker), where I often use powerful regex hacks and command-line wizardry to accomplish complex tasks with minimal code.
Remember, in the world of system administration, efficiency and reliability are key. This template helps me achieve both, allowing me to focus on solving problems rather than setting up scaffolding. Happy scripting, fellow sysadmins!