NAME
    Sys::Run::Safer - Run external commands, with a safer API

VERSION
    This document describes version 0.03 of Sys::Run::Safer (from Perl
    distribution Sys-Run-Safer), released on 2014-12-24.

SYNOPSIS
     use Sys::Run::Safer qw(run);
     run(
         prog => 'rm',
         opts => ['-rf', '--interactive=never'],
         args => ['file1', 'file2', 'dir1'],
     ) == 0 or die;

    Will run "system('rm', '-rf', '--interactive=never', '--', 'file1',
    'file2', 'dir1')". Upon failure ($? is not zero), will print diagnostic
    error message. Return value is the same as Perl's "system()".

DESCRIPTION
    Status: experimental, prone to change.

    This module is an experiment to provide a safer API alternative to
    Perl's "system()" for executing external commands, particularly commands
    that follow the POSIX syntax/GNU extension of accepting command-line
    options/arguments.

    The problem with Perl's "system()" API is that it *may or may not*
    execute shell, with relatively complicated rule. Even if you use the
    list form, e.g. "system 'cmd', @args" it will still use a shell if @args
    happens to be empty. To always avoid the shell you'll have to use the
    so-called third form: " system { 'cmd' } 'cmd', @args" which is
    practically never used by casual programmers, including me. Executing
    shell sometimes is desired, but brings many consequences like
    wildcard/pathname expansion, among many other things. You have to be
    careful to quote every input/argument (e.g. using String::ShellQuote).

    This module's "run()" currently never invokes shell, by using the third
    form of "system()". A way to use shell might be provided in the future,
    but will force the programmer to explicitly express so.

    There are other CPAN modules that do this (making it clearer when to use
    shell or not), BTW, e.g. IPC::System::Simple which provides additional
    "systemx" function which never invokes the shell.

    Another problem that is seldom addressed by other modules is that
    programs can mistakenly interpret argument (e.g. filename) as option if
    that argument happens to start with dash. An example (see [1] for more
    details) is when there is a file named "--checkpoint-action=exec=sh
    shell.sh") and you feed it to "tar". Even after you avoid shell or quote
    the argument, the filename will still be interpreted as an option (and
    thus the payload shell script executed by "tar") unless you precede the
    argument in the command with "--". Which is all too easy to be
    forgotten.

    Thus, the "run()" API is designed to force you to enter option and
    argument separately, and automatically add a "--" after the options.

FUNCTIONS
  run(%args) -> bool
    Run external commands, with a safer API.

    Arguments ('*' denotes required arguments):

    *   args => *array*

    *   opts => *array*

    *   prog* => *str*

    Return value:

     (bool)

FAQ
  What about feeding STDIN, capturing STDOUT/STDERR, timeouts, ...?
    I plan to incorporate this API, should the API prove to be not too
    annoying to use, into Proc::Govern. The latter module supports (or
    will/should support) all kinds of child-controlling features.

TODO
SEE ALSO
    [1]
    <http://www.defensecode.com/public/DefenseCode_Unix_WildCards_Gone_Wild.
    txt>

    Perl's "system()" documentation ("perldoc -f system").

    There are lots and lots of CPAN modules dealing with running external
    commands. Some offer only improvement/alternative for Perl's "system()",
    others provide extra features (from feeding input and capturing output,
    timeout, adding logging/debugging, retry, and so on). I'll limit here to
    listing the modules of the former group:

    *   IPC::System::Simple

        Provides a separate function "systemx()" which never invokes the
        shell. Also provides run() and runx() which dies on failure instead
        of just returning non-zero.

    *   IPC::Run

        Recommended over the core IPC::Cmd. "IPC::Run"'s "run()" won't run
        shell if you feed it arrayref (e.g. "<run ["ls"]"> instead of "<run
        "ls""> even though there is only one element in the array (i.e.
        "<run ["ls -l"]"> or "<run ["ls | sort"]"> won't work). While
        "IPC::Cmd"'s "run" will still run shell in the latter case, just
        like Perl's "system()".

        Note that "IPC::Run" also has extra features for controlling the
        child process, and is used by some other modules as a backend.

HOMEPAGE
    Please visit the project's homepage at
    <https://metacpan.org/release/Sys-Run-Safer>.

SOURCE
    Source repository is at
    <https://github.com/perlancar/perl-Sys-Run-Safer>.

BUGS
    Please report any bugs or feature requests on the bugtracker website
    <https://rt.cpan.org/Public/Dist/Display.html?Name=Sys-Run-Safer>

    When submitting a bug or request, please include a test-file or a patch
    to an existing test-file that illustrates the bug or desired feature.

AUTHOR
    perlancar <perlancar@cpan.org>

COPYRIGHT AND LICENSE
    This software is copyright (c) 2014 by perlancar@cpan.org.

    This is free software; you can redistribute it and/or modify it under
    the same terms as the Perl 5 programming language system itself.

