Creating an Automated Scripting Application with Perl
From Development to Deployment
In this guide, we’ll build an automated scripting application using Perl to execute predefined scripts for tasks like data processing, system maintenance, report generation, or automated testing. We’ll use Strawberry Perl and Berrybrew for Windows environments, and perlbrew for Linux or WSL (Windows Subsystem for Linux). Let’s get started!
Prerequisites
Before proceeding, ensure your system is ready. The setup depends on your operating system:
- Linux or WSL: You’re set to use perlbrew for managing Perl versions. Install a Linux distribution on WSL if using Windows (e.g., Ubuntu via Microsoft Store), then install perlbrew (see Step 12).
- Windows (without WSL): You won’t have native Unix tools, so install these:
Strawberry Perl: A full Perl environment for Windows. Download from strawberryperl.com.
Berrybrew: A Perl version manager for Windows. Get it from GitHub.
Verify installations:
- Windows: perl -v (after Strawberry Perl) and berrybrew version (after Berrybrew).
- Linux/WSL: perl -v (after perlbrew setup).
Step-by-Step Guide
Step 1: Install Strawberry Perl (Windows Only)
- If on Linux or WSL: Skip to Step 3.
- Download and install Strawberry Perl from strawberryperl.com. Follow the installer’s instructions.
- Verify: Open a terminal (e.g., Command Prompt) and run perl -v. You should see the Perl version.
Step 2: Install Berrybrew (Windows Only)
- If on Linux or WSL: Skip to Step 3.
- Download Berrybrew from its GitHub page and follow the installation steps.
- Verify: Run berrybrew version in your terminal.
Step 3: Set Up the Project Directory
Create an organized structure for your project. Open a terminal and run:
mkdir AutoPerl
cd AutoPerl
mkdir bin config lib local logs scripts t
- Purpose: These directories hold your scripts (scripts), configuration (config), libraries (lib), logs (logs), and more.
- Note: We’ll use “AutoPerl” as the project name throughout.
Step 4: Create the Configuration File
In the config directory, create app_config.yaml to define scripts and log location:
# Configuration settings for AutoPerl
scripts:
- name: Example Script
path: scripts/example_script.pl
- name: Another Script
path: scripts/another_script.pl
logs: logs/example.log
Step 5: Create the Main Script
In the bin directory, create run.pl. This script loads the config, initializes the runner, and executes scripts:
#!/usr/bin/env perl
use strict;
use warnings;
use FindBin;
use lib "$FindBin::Bin/../lib"; # Add lib to @INC
use lib "$FindBin::Bin/../local/lib/perl5"; # Add local lib to @INC
use AutomatedScriptingApp::ScriptRunner;
use AutomatedScriptingApp::Config;
# Load configuration
my $config_file = "$FindBin::Bin/../config/app_config.yaml";
my $config = AutomatedScriptingApp::Config->new($config_file) or die "Failed to load config: $!\n";
# Initialize the script runner
my $script_runner = AutomatedScriptingApp::ScriptRunner->new($config) or die "Failed to initialize script runner\n";
# Run the scripts
$script_runner->run_scripts();
- Improvements: Added basic error handling for config and runner initialization.
Step 6: Create the Config Module
In lib/AutomatedScriptingApp, create Config.pm to load the YAML file:
package AutomatedScriptingApp::Config;
use strict;
use warnings;
use YAML::XS 'LoadFile';
sub new {
my ($class, $file) = @_;
my $self = bless {}, $class;
eval { $self->{config} = LoadFile($file) };
if ($@) {
warn "Error loading config file '$file': $@";
return undef;
}
return $self;
}
sub get_config { shift->{config} }
1;
- Improvements: Returns the object ($self) properly, adds an accessor (get_config), and handles YAML loading errors.
Step 7: Create the Script Runner Module
In lib/AutomatedScriptingApp, create ScriptRunner.pm to execute scripts:
package AutomatedScriptingApp::ScriptRunner;
use strict;
use warnings;
use AutomatedScriptingApp::Utils;
sub new {
my ($class, $config) = @_;
my $self = bless { config => $config }, $class;
return $self;
}
sub run_scripts {
my ($self) = @_;
my $config = $self->{config}->get_config;
my $scripts = $config->{scripts} or die "No scripts defined in config\n";
foreach my $script (@$scripts) {
my $path = $script->{path} or next;
unless (-e $path) {
AutomatedScriptingApp::Utils::log_message("Error: Script '$path' not found");
next;
}
AutomatedScriptingApp::Utils::log_message("Running script: $path");
system("perl", $path) == 0 or warn "Script '$path' failed: $?\n";
}
}
1;
- Improvements: Validates script paths, uses config accessor, improves error handling for script execution.
Step 8: Create the Utils Module
In lib/AutomatedScriptingApp, create Utils.pm for logging:
package AutomatedScriptingApp::Utils;
use strict;
use warnings;
use Exporter 'import';
use File::Basename;
use File::Spec;
our @EXPORT_OK = qw(log_message);
sub log_message {
my ($message) = @_;
my $log_file = File::Spec->catfile(dirname(__FILE__), '../../logs/example.log');
open my $fh, '>>', $log_file or do {
warn "Could not open log file '$log_file': $!";
return;
};
print $fh "$message\n";
close $fh;
}
1;
- Improvements: Adds error handling for log file access, avoids die for non-fatal logging failures.
Step 9: Create Example Scripts
In the scripts directory, create these sample scripts:
example_script.pl
#!/usr/bin/env perl
use strict;
use warnings;
print "Hello from example_script.pl!\n";
another_script.pl
#!/usr/bin/env perl
use strict;
use warnings;
print "Hello from another_script.pl!\n";
Step 10: Prepare the Log Directory
In the logs directory, create README.md:
# Log Directory
This directory stores logs generated by AutoPerl. The main log file is `example.log`.
Step 11: Clear the Log File
In scripts, create clear_log.pl:
#!/usr/bin/env perl
use strict;
use warnings;
my $log_file = 'logs/example.log';
if (-e $log_file) {
open my $fh, '>', $log_file or die "Could not clear log file: $!";
close $fh;
print "Log file cleared successfully.\n";
} else {
print "No log file to clear.\n";
}
- Improvements: Checks if the file exists before clearing.
Step 12: Configure Perl Environment
- Windows (Berrybrew):
berrybrew install 5.32.1_64
berrybrew switch 5.32.1_64
Verify: perl -v shows 5.32.1.
- Linux/WSL (perlbrew):
Install perlbrew:
curl -L https://install.perlbrew.pl | bash source ~/perl5/perlbrew/etc/bashrc
- Then install and switch Perl:
perlbrew install perl-5.32.1 perlbrew switch perl-5.32.1
- Verify: perl -v.
Step 13: Install Required Perl Modules
Install cpanm if not present:
- Windows: cpan App::cpanminus
- Linux/WSL: perlbrew install-cpanm
Then install dependencies:
cpanm YAML::XS
- Note: Explicitly installs YAML::XS, the only external dependency.
Step 14: Run the Application
Navigate to your project directory (replace with your actual path):
cd /path/to/AutoPerl # e.g., C:\Git\AutoPerl or ~/AutoPerl
perl bin/run.pl
Packaging Your Application
Once tested, package your app for distribution:
Dist::Zilla (Latest: 6.032):
- Install: cpanm Dist::Zilla
- Create a dist.ini and run dzil build for a distributable tarball. Ideal for complex projects.
Module::Build (Latest: 0.4234) or ExtUtils::MakeMaker (Latest: 7.70):
- Generate a Build.PL or Makefile.PL with module-starter, then perl Build.PL && ./Build dist.
Docker:
- Example Dockerfile:
FROM perl:5.32
COPY . /app
WORKDIR /app
RUN cpanm YAML::XS
CMD ["perl", "bin/run.pl"]
- Build: docker build -t autoperl.
- Script Wrapping:
- Use pp (from PAR::Packer): pp -o autoperl bin/run.pl to bundle with dependencies.
Deployment Options
Deploy based on your needs:
- Local Servers/Workstations: Run directly for internal automation.
- Cloud Services: Use AWS Lambda (via Perl layers), Google Cloud Run, or Azure VMs. Check Perl version support.
- Virtual Machines: Spin up a VM with your preferred OS and Perl setup.
- Containerization: Deploy with Docker or Kubernetes for scalability (e.g., docker run autoperl).
Troubleshooting
- “Module not found”: Run cpanm YAML::XS again.
- “Permission denied”: Ensure you have write access to the logs directory.
- No output: Check logs/example.log for errors.
Conclusion
You’ve built a robust, automated scripting application in Perl! It’s configurable, logs execution details, and can scale with new scripts or features. Try tweaking the config or adding scripts to suit your needs.
Here is an example of the build, the repos kind of messy and doesn’t make complete sense but I’ll update everything later. For now, use the repo as a reference with the article.
License
This project is licensed under the MIT License.