Name
Shell::Tools - Perl extension to reduce boilerplate in Perl shell scripts
Synopsis
use Shell::Tools; # is the same as the following:
use warnings;
use strict;
use IO::File ();
use IO::Handle ();
use Carp qw/carp croak confess/;
use Pod::Usage 'pod2usage';
use Getopt::Std 1.04 'getopts';
sub main::HELP_MESSAGE { ... } # calls pod2usage()
sub main::VERSION_MESSAGE { ... } # see documentation below
$Getopt::Std::STANDARD_HELP_VERSION = 1; # exit after --help or --version
use Cwd qw/getcwd cwd abs_path/;
use File::Spec::Functions qw/canonpath catdir catfile curdir rootdir updir
no_upwards file_name_is_absolute splitdir abs2rel rel2abs/;
use File::Basename qw/fileparse basename dirname/;
use File::Temp qw/tempfile tempdir/;
use File::Copy qw/move copy/;
use File::Path 2.08 qw/make_path remove_tree/;
use File::Find 'find';
use Fcntl qw/LOCK_SH LOCK_EX LOCK_UN LOCK_NB SEEK_SET SEEK_CUR SEEK_END/;
use FindBin ();
use Data::Dumper 'Dumper';
use Scalar::Util 'looks_like_number';
use List::Util qw/first reduce/;
Description
This module exports a collection of functions from several core Perl modules which can often be very useful when writing Perl shell scripts.
See also Shell::Tools::Extra, which exports additional CPAN modules' functions and classes.
Warning
This module is intended to help write short, simple shell scripts. Because of its many exports it is not recommended for large applications, CGI scripts, object-oriented applications and the like.
Version
This document describes version 0.04 of Shell::Tools.
Exports
This module exports the following modules and functions.
Each module has an Exporter tag that is the same name as the module. This is useful if you want to exclude some modules' functions from being exported, for example use Shell::Tools qw/ !:File::Copy /;
.
warnings and strict
These are enabled in the calling script. (No Exporter tag.)
IO::File and IO::Handle
These modules are loaded, nothing is exported. (No Exporter tag.)
Perl before v5.14 did not load these automatically. Loading these modules allows you to do things like:
open my $fh, ">", $file or die $!;
$fh->autoflush(1);
$fh->print("Hello");
# Note: calling binmode this way may not work on older Perls
$fh->binmode(":raw");
Carp
Carp's carp
, croak
and confess
.
Getopt::Std and Pod::Usage
=head1 SYNOPSIS
foo.pl [OPTIONS] FILENAME
OPTIONS:
-f - foo
-b BAR - bar
=cut
getopts('fb:', \my %opts) or pod2usage;
pod2usage("must specify a filename") unless @ARGV==1;
This module provides the functions main::HELP_MESSAGE
and main::VERSION_MESSAGE
. HELP_MESSAGE
simply calls pod2usage. VERSION_MESSAGE
first checks for $main::VERSION_STRING
and prints that if available, otherwise it will use $main::VERSION
to construct a message, and if neither is available, it will use the "last modified" time of the script. Also, $Getopt::Std::STANDARD_HELP_VERSION
is set, so the getopts
call will exit the script if it sees --help
or --version
.
We require Getopt::Std 1.04 or greater for the support of the --help
and --version
switches.
Note that Pod::Usage before Version 1.36 only looked for a POD section titled SYNOPSIS
; from 1.36 upwards it also looks for a section titled USAGE
(note uppercase is always important).
Cwd
my $cwd = getcwd(); # POSIX getcwd(3)
my $cwd = cwd();
my $abs_path = abs_path($file); # realpath(3)
File::Spec::Functions
my $path = canonpath($path);
my $path = catdir(@dirs);
my $path = catfile(@dirs, $filename);
my @paths = no_upwards(@paths);
my $is_abs = file_name_is_absolute($path);
my @dirs = splitdir($directories);
# note abs2rel() and rel2abs() use Cwd::cwd() if $base is omitted
my $rel_path = abs2rel($path, $base);
my $abs_path = rel2abs($path, $base);
my $curdir = curdir(); # e.g. "."
my $rootdir = rootdir(); # e.g. "/"
my $updir = updir(); # e.g. ".."
# Hint - one way to list all entries in a directory:
my @files = do { opendir my $dh, "." or die $!; no_upwards readdir $dh };
See File::Spec for docs.
Note the additional Exporter tag File::Spec
is provided as an alias for File::Spec::Functions
.
File::Basename
my $filename = fileparse($path, @suffixes); # suffixes optional
my ($filename, $dirs, $suffix) = fileparse($path, @suffixes);
$path = $dirs . $filename . $suffix;
The functions basename
and dirname
are also provided for compatibility, but File::Basename says that fileparse
is preferred.
File::Temp
my $fh = tempfile();
my ($fh,$fn) = tempfile(UNLINK=>1);
my (undef,$fn) = tempfile(OPEN=>0);
my $tmpdir = tempdir(CLEANUP=>1);
File::Copy
copy("src","dst") or die "Copy failed: $!";
move("src","dst") or die "Move failed: $!";
File::Path
# will carp and croak
make_path('foo/bar/baz', '/quz/blah');
remove_tree('foo/bar/baz', '/quz/blah');
Note that we require File::Path 2.08 or greater because its interface has undergone several changes and its documentation strongly recommends using this version or newer.
File::Find
find({ no_chdir=>1, wanted=>sub {
return if -d;
...;
} }, @DIRS);
Fcntl (selected)
SEEK_*
(seek) and LOCK_*
(flock)
FindBin
Nothing is exported; use these variables: $FindBin::Bin
, $FindBin::Script
, $FindBin::RealBin
, and $FindBin::RealScript
Data::Dumper
print Dumper(\%ENV);
Scalar::Util (selected)
my $nr = "123.45";
print "$nr looks like a number" if looks_like_numer($nr);
List::Util (selected)
# first is more efficient than grep for boolean tests
my $found = first { /3/ } 10..20;
my $maxval = reduce { $a > $b ? $a : $b } 1..10;
See Also
Shell::Tools::Extra - extension of this module that also exports several functions from several CPAN modules
Env - imports environment variables as scalars or arrays
use Env qw(HOME USER @PATH);
File::stat - by-name interface to Perl's built-in stat() functions
my $st = stat($filename) or die $!; print "$filename is executable\n" if $st->mode & 0111; print "$filename has links\n" if $st->nlink > 1;
Please see the "Bugs" section of File::stat -
$_
and_
(currently) do not work withstat
andlstat
!-
Since slurping a file can be as simple as the following, it's left up to the user to import this module if desired.
my $slurp = do { open my $fh, '<', $filename or die $!; local $/; <$fh> };
Configuration file parsers: Config::General, Config::Perl (one of my modules), Config::IniFiles, Config::INI (simpler INI files), and Config::Tiny (even simpler INI files). For XML, JSON, and YAML, there are many modules available, some examples are: YAML::XS, XML::Simple, and JSON.
Author, Copyright, and License
Copyright (c) 2014 Hauke Daempfling (haukex@zero-g.net).
This library is free software; you can redistribute it and/or modify it under the same terms as Perl 5 itself.
For more information see the Perl Artistic License, which should have been distributed with your copy of Perl. Try the command "perldoc perlartistic
" or see http://perldoc.perl.org/perlartistic.html.