Provided by: libscriptalicious-perl_1.16-1_all bug


       Scriptalicious - Make scripts more delicious to SysAdmins


        use Scriptalicious
             -progname => "pu";

        our $VERSION = "1.00";

        my $url = ".";
        getopt getconf("u|url" => \$url);

        run("echo", "doing something with $url");
        my $output = capture("svn", "info", $url);


        =head1 NAME

        pu - an uncarved block of wood

        =head1 SYNOPSIS

        pu [options] arguments

        =head1 DESCRIPTION

        This script's function is to be a blank example that many
        great and simple scripts may be built upon.

        Remember, you cannot carve rotten wood.



        =item B<-h, --help>

        Display a program usage screen and exit.

        =item B<-V, --version>

        Display program version and exit.

        =item B<-v, --verbose>

        Verbose command execution, displaying things like the
        commands run, their output, etc.

        =item B<-q, --quiet>

        Suppress all normal program output; only display errors and

        =item B<-d, --debug>

        Display output to help someone debug this script, not the
        process going on.



       This module helps you write scripts that conform to best common practices, quickly.  Just
       include the above as a template, and your script will accept all of the options that are
       included in the manual page, as well as summarising them when you use the "-h" option.

       (Unfortunately, it is not possible to have a `use' dependency automatically add structure
       to your POD yet, so you have to include the above manually.  If you want your help message
       and Perldoc to be meaningful, that is.)

       Shortcuts are provided to help you abort or die with various error conditions; all of
       which print the name of the program running (taken from $0 if not passed).  The motive for
       this is that "small" scripts tend to just get written and forgotten; so, when you have a
       larger system that is built out of lots of these pieces it is sometimes guesswork figuring
       out which script a printed message comes from!

       For instance, if your program is called with invalid arguments, you may simply call
       "abort" with a one-line message saying what the particular problem was.  When the script
       is run, it will invite the person running the script to try to use the "--help" option,
       which gives them a summary and in turn invites them to read the Perldoc.  So, it reads
       well in the source;

         @ARGV and abort "unexpected arguments: @ARGV";
         $file or abort "no filename supplied";

       And in the output;

         somescript: no filename supplied!
         Try `somescript --help' for a summary of options

       On the other hand, if you call "barf", then it is considered to be a hard run-time
       failure, and the invitation to read the "--help" page to get usage not given.  Also, the
       messages are much tidier than you get with "die" et al.

         open FOO, "<$file" or barf "failed to open $file; $!";

       Which will print:

         somescript: failed to open somefile; Permission denied

       Scriptalicious has no hard dependencies; all the methods, save reading passwords from the
       user, will work in the absence of extra installed modules on all versions of Perl from
       5.6.0 onwards.

       To avoid unnecessary explicit importing of symbols, the following symbols and functions
       are exported into the caller's namespace:

           Set to 0 by default, and 1 if "-v" or "--verbose" was found during the call to
           "getopt()".  Extra "-v"'s or "--debug" will push this variable higher.  If "-q" or
           "--quiet" is specified, this will be less than one.

           It is recommended that you only ever read this variable, and pass it in via the
           import.  This is not automatically extracted from the POD for performance reasons.

           Name of the configuration file.  Set before a call to "getconf", or read afterwards to
           see if a config file was used.  New in Scriptalicious 1.16

           Fetch arguments via "Getopt::Long::GetOptions".  The "bundling" option is enabled by
           default - which differs from the standard configuration of Getopt::Long.  To alter the
           configuration, simply call "Getopt::Long::config".  See Getopt::Long for more

           Just like "getopt()", but doesn't cause a fatal error if there are any unknown

           Fetches configuration, takes arguments in the same form as getopt()..

           The configuration file is expected to be in ~/.PROGNAMErc, /etc/perl/PROGNAME.conf, or
           /etc/PROGNAME.conf.  Only the first found file is read, and unknown options are
           ignored for the time being.

           The file is expected to be in YAML format, with the top entity being a hash, and the
           keys of the hash being the same as specifying options on the command line.  Using YAML
           as a format allows some simplificiations to getopt-style processing - "=s%" and "=s@"
           style options are expected to be in a real hash or list format in the config file, and
           boolean options must be set to "true" or "false" (or some common equivalents).

           Returns the configuration file as Load()'ed by YAML in scalar context, or the argument
           list it was passed in list context.

           For example, this minimal script (missing the documentation, but hey at least it's a

             getopt getconf
                 ( "something|s" => \$foo,
                   "invertable|I!" => \$invertable,
                   "integer|i=i" => \$bar,
                   "string|s=s" => \$cheese,
                   "list|l=s@" => \@list,
                   "hash|H=s%" => \%hash, );

           Will accept the following invocation styles;


    --no-invertable    <=== FORM DIFFERS IN CONFIG FILE
    --list one --list two --list three
    --hash foo=bar --hash baz=cheese

           Equivalent config files:

             something: 1

             invertable: on

             invertable: off

             integer: 7

             string: anything

               - one
               - two
               - three

             list: [ one, two, three ]

               foo: bar
               baz: cheese

           Note that more complex and possibly arcane usages of Getopt::Long features may not
           work with getconf (patches welcome).

           This can be handy for things like database connection strings; all you have to do is
           make an option for them, and then the user of the script, or a SysAdmin can set up
           their own config file for the script to automatically set the options.

       getconf_f($filename, @getopt_args)
           As getconf(), but specify a filename.

       say "something"
           Prints a message to standard output, unless quiet mode ("-q" or "--quiet") was
           specified.  For normal program messages.

       mutter "progress"
           Prints a message to standard output, if verbose mode ("-v") or debug mode ("-d") is
           enabled (ie, if "$VERBOSE > 0").  For messages designed to help a user of the script
           to see more information about what is going on.

       whisper "detail"
           Prints a message to standard output, if debug mode ("-d") is enabled or multiple
           verbose options were passed (ie, if "$VERBOSE > 1").  For messages designed to help a
           person debugging the script to see more information about what is going on internally
           to the script.

       abort "won't go to sea in a storm"
           Prints a short program usage message (extracted from the POD synopsis) and exits with
           an error code.

       moan "weather is miserable"
           Prints a warning to standard error.  It is preceded with the text "warning:".  The
           program does not exit.

       protest "don't know the weather report"
           Prints an error message to standard error.  It is preceded with the text "error:".
           The program does not exit.

       barf "hit an iceberg"
           Prints a warning to standard error.  It is preceded with the text "warning:".  The
           program does not exit.

       run("command", "arg1", "arg2")
           Runs a command or closure, barf's with a relevant error message if there is a problem.
           Program output is suppressed unless running in verbose mode.

           "run()" and the three alternatives listed below may perform arbitrary filehandle
           redirection before executing the command.  This can be a very convenient way to do
           shell-like filehandle plumbing.

           For example;

             run( -in => sub { print "Hello, world!\n" },
                  -out => "/tmp/outfile",
                  -out2 => "/dev/null",
                  @command );

           This will connect the child process' standard input ("-in") to a closure that is
           printing ""Hello, world!\n"".  The output from the closure will appear on standard
           input of the run command.  Note that the closure is run in a sub-process and so will
           not be able to set variables in the calling program.

           It will also connect the program's standard output ("-out") to "/tmp/outfile", and its
           standard error (filehandle 2) to "/dev/null" (the traditional way of junking error

           If you wanted to connect two filehandles to the same place, you could pass in "GLOB"
           references instead;

             run( -out => \*MYOUT,
                  -out2 => \*MYOUT,
                  @command );

           Any filehandle can be opened in any mode; "-in" merely defaults to meaning "-in0", and
           "-out" defaults to meaning "-out1".  There is no "-err"; use "-out2".  "-rw" exists
           (defaulting to "-rw0"), but is probably of limited use.

           Here is an example of using "prompt_passwd()" to hijack "gpg"'s password grabbing;

             my $password = prompt_passwd("Encryption password: ");
             my $encrypted = run( -in4 => sub { print "$password\n" },
                                  "gpg", "--passphrase-fd", "4", "-c", $file )

       run_err("command", "arg2", "arg1")
           Same as run, but returns the error code rather than assuming that the command will
           successfully complete.  Again, output it suppressed.

       capture("command", "1gra", "2gra")
           runs a command, capturing its output, barfs if there is a problem.  Returns the output
           of the command as a list or a scalar.

       capture_err("command", "foo")
           Works as capture, but the first returned item is the error code of the command ($?)
           rather than the first line of its output.  Also, it only ever returns the output as a


              my ($rc, @output) = capture_err("somecommand", @args);

           "hush_exec" is used to indicate that the programs you are running are only of interest
           to someone debugging the script.  So, the messages showing commands run and giving
           execution timings will not be printed without "-vv" (double verbose) or "-d" (debug,
           which is the same thing).

           These three little functions are for printing run times in your scripts.  Times are
           displayed for running external programs with verbose mode normally, but this will let
           you display running times for your main program easily.

       sci_unit($num, [$unit, $precision])
           Returns a number, scaled using normal scientific prefixes (from atto to exa).
           Optionally specify a precision which is passed to sprintf() (see "sprintf" in
           perldoc).  The default is three significant figures.

           From Scriptalicious 1.08, the "u" character is used in place of the Greek "mu" due to
           encoding compatibility issues.

       time_unit($num, [$precision])
           Converts a floating point number of seconds to a human-readable time, the precision
           specifies the number of significant decimal digits, which is used to compute a
           "quanta" for the value given, values below which are not displayed.  $precision
           defaults to 4.


            time_unit(10.1) => "10.10s"
            time_unit(1) => "1.000s"
            time_unit(0.1) => "100ms"
            time_unit(86401,2) => "1d 0h"
            time_unit(86401,3) => "1d 0h"
            time_unit(86401) => "1d 0h:0m"
            time_unit(86400+3600/2) => "1d 0h:30m"
            time_unit(86401,5) => "1d 0h:0m:1s"
            time_unit(7*86400) => "1w0d 0h"

       prompt_regex($prompt, qr/(.*)/)
           Prompts for something, using the prompt "$prompt", matching the entered value (sans
           trailing linefeed) against the passed regex.

           Note that this differs from the previous behaviour of prompt_regex, which took a sub.

       prompt_sub($prompt, sub { /(.*)/ && $1 })
           Prompts for something, using the prompt "$prompt", feeding the sub with the entered
           value (sans trailing linefeed), to use a default, the passed sub should simply return
           it with empty input.

           Same as "prompt_regex", but turns off echo.  $prompt defaults to ""Password: "" for
           this function.

           Prompt for a string.

           get an integer

       prompt_for([ [$type =] $what])>
           Prompts for a value for $what.  This constructs a prompt saying, eg ""Enter value for
           $what"".  Calls the equivalent "prompt_foo()" method.

           prompts for yes or no, presuming neither

           prompts for yes or no, presuming yes and no, respectively.

           You can also spell these as "prompt_nY" and "prompt_Ny".

           Dump $ref via "YAML", falling back to "Data::Dumper" if YAML fails to load (or dies
           during the dump).  Returns a string.

       tsay($template, $vars)
           Prints the template $template with $vars.  $template may be included at the end of the
           file as a data section, for instance:

            use Scriptalicious;

            tsay hello => { name => "Bernie" };


            Hello, [% name %]
            [% INCLUDE yomomma %]
            Yo momma's so fat your family portrait has stretchmarks.

           This will print:

            Hello, Bernie
            Yo momma's so fat your family portrait has stretchmarks.

           Note that the script goes to lengths to make sure that the information is always
           printed whether or not Template Toolkit is installed.  This gets pretty verbose, but
           at least solves the "argh!  that script failed, but I don't know why because it needed
           this huge dependency to tell me" problem.

           For example, the above would be printed as:


           If you've got a short little Perl function that implements something useful for people
           writing Shell scripts in Perl, then please feel free to contribute it.  And if it
           really is scriptalicious, you can bet your momma on it getting into this module!


       Simon Cozen's Getopt::Auto module does a very similar thing to this module, in a quite
       different way.  However, it is missing "say", "run", etc.  So you'll need to use some
       other module for those.  But it does have some other features you might like and is
       probably engineered better.

       There's a template script at "Documentation and help texts" in Getopt::Long that contains
       a script template that demonstrates what is necessary to get the basic man page / usage
       things working with the traditional Getopt::Long and Pod::Usage combination.

       Getopt::Plus is a swiss army chainsaw of Getopt::* style modules, contrasting to this
       module's approach of elegant simplicity (quiet in the cheap seats!).

       Getopt::EUCLID is Damian Conway's take on this.

       Finally, if you don't mind the dependencies of Moose (or Mouse), then MooseX::Getopt and
       MooseX::SimpleConfig are much more elegant approaches to getopt handling and configuration
       than this module.

       If you have solved this problem in a new and interesting way, or even rehashed it in an
       old, boring and inelegant way and want your module to be listed here, please contact the


       Sam Vilain,

       Copyright 2005-2008, Sam Vilain.  All rights reserved.  This program is free software; you
       can use it and/or distribute it under the same terms as Perl itself; either the latest
       stable release of Perl when the module was written, or any subsequent stable release.

       Please note that this applies retrospectively to all Scriptalicious releases; apologies
       for the lack of an explicit license.