Command::Template - A template to build command line arrays, and run them
This document describes Command::Template version 0.001.
use Command::Template qw< command_runner command_template cr ct >; #### COMMAND EXPANSION GENERATION (NO EXECUTION) #### # command_template is aliased to ct my $ct = command_template(qw{ ls [options=-l] <dir> }); # @c1 = qw< ls -l / > my @c1 = $ct->generate(dir => '/'); # @c2 = qw< ls -la / > my @c2 = $ct->generate(dir => '/etc', options => '-la'); # @c3 = @c4 = qw< ls /usr/bin > my @c3 = $ct->generate(dir => '/usr/bin', options => undef); my @c4 = $ct->generate(dir => '/usr/bin', options => []); # @c5 = qw< ls -l -a /usr/bin > my @c5 = $ct->generate(dir => '/usr/bin', options => [qw< -l -a >]); #### COMMAND RUNNING (VIA IPC::Run) #### # command_runner is aliased to cr my $runner = command_runner(qw{ ls [options=-l] <dir> }); # run command qw< ls -l / >, returns a Command::Template::RunRecord my $r = $runner->run(dir => '/'); my $run_successful = $r->success; my $exit_code = $r->exit_code; # 0 is OK as usual in UNIX my $received_signal = $r->signal; # e.g. if killed, ... my $stdout = $r->stdout; my $stderr = $r->stderr; my $merged = $r->merged; # stderr then stdout, no newlines # added # command_runner is aliased to cr my $other_runner = cr(qw< cat >); # gives stdin as stdout my $message = "blah\nblah"; $r = $other_runner->run(-stdin => $message); my $equal = $r->stdout eq $message; # true
Command::Template eases the creation of objects that help building up command-lines and/or to run them.
Command::Template
As an example, it might be needed to generate multiple commands according to the following template:
ls [options=-l] <dir>
i.e. the ls command, where there might be some options (defaulting to option -l) and there MUST be a directory dir (which in this case has no default).
ls
options
-l
dir
The following possible expansions adhere to the template above:
ls -l / ls -la /usr ls -l -a /etc ls /run
while the following does not (because there is no directory, which we want because we used the <...> form):
<...>
ls -l
The module provides two different interfaces:
"command_template" allows generating the commands as lists, which are then supposed to be used somehow (e.g. provided to system);
system
"command_runner" allows running the commands via IPC::Run.
Both adhere to the same "Expansion Rules" explained below and implemented in Command::Template::Instance.
A template in Command::Template resembles the way commands are explained in documentation:
required parameters are enclosed by <...> delimiters;
optional parameters are enclosed by [...] delimiters.
[...]
Parameters name can only start with a letter or an underscore, then can be followed by any sequence of underscores, letters, and digits. The following names are valid:
foo bar dir baz1 baz_2 name_or_surname
Any parameter can be optionally set with a default value, which can be set with the = sign, like in the following examples:
=
<foo=this is FOO> <bar= BAR >
Spaces are preserved starting immediately after the = sign.
When Template::Command::Instance expands a template, it uses a hash that maps each name to the value it should take:
if undef, then the corresponding item is removed from the command. This allows getting rid of a default value set for an optional parameter; it is an error (leading to an exception) if the parameter is required;
undef
if any other plain scalar, it is set as the value in the specific command line parameter location;
if an array reference, all items inside are put in the specific command line parameter location.
The last possibility provides the flexibility to e.g. set options that require a parameter (e.g. it would be the case of option -name for command find).
-name
find
While Command::Template::Instance only allows generating command lines as lists of strings, Command::Template::Runner allows running them by means of IPC::Run.
All the heavy work for expanding is provided by Command::Template::Instance behind the scenes; the "SYNOPSIS" contains examples of actual running of commands.
# parse a command line template and use it for running commands my $cr = command_runner(qw{ ls [options=-l] <dir> });
Returns a Command::Template::Runner object with a run method that allows actually running generated commands via IPC::Run.
run
Each run returns a Command::Template::Runner::Record object that allows peeking into the actual result of the run.
my $r = $cr->run(options => '-la', '/etc'); say $r->stdout if $r->success;
Alias for "command_runner".
my $ct = command_template(qw{ galook <foo> <bar=N> [baz] [sil=Y] })
Returns a Command::Template::Instance object with a generate method that performs the actual expansion, returning a list of strings representing the command line.
generate
Alias for "command_template".
If extending Command::Template is of interest, here are a few hints:
class Command::Template::Instance encapsulates parsing a command template and expanding it for generating command lists, based on a hash with values binding;
class Command::Template::Runner provides a simple running facility around Command::Template::Instance that uses IPC::Run to run expanded commands, returning the result as a Command::Template::Runner::Record object.
class Command::Template::Runner::Record provides accessors into the outcome of a single run from Command::Template::Runner.
Possible reasons for expanding might be:
different or additional rules for expansions are needed. If this is the case, the alternative to Command::Template::Instance must provide a generate method; Comman::Template::Runner can still be used, as long as a reference to the alternative object for the instance is passed to the constructor.
a different running facility is needed. In this case, it suffices to impelement a new runner class, leveraging Command::Template::Instance for the command expansion.
Minimum perl version 5.24.
Report bugs through GitHub (patches welcome) at https://github.com/polettix/Command-Template.
Flavio Poletti <flavio@polettix.it>
Copyright 2021 by Flavio Poletti <flavio@polettix.it>
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
To install Command::Template, copy and paste the appropriate command in to your terminal.
cpanm
cpanm Command::Template
CPAN shell
perl -MCPAN -e shell install Command::Template
For more information on module installation, please visit the detailed CPAN module installation guide.