NAME

Sys::Cmd - run a system command or spawn a system processes

VERSION

v0.985.2 (2025-12-01)

SYNOPSIS

use Sys::Cmd qw/run runsub spawn/;

my $output   = run( 'ls', '--long' );    # /usr/bin/ls --long
my @numbered = run( 'cat', '-n',         # /usr/bin/cat -n <<EOF
    {                                    # > X
        input => "X\nY\nZ\n",            # > Y
    }                                    # > Z
);                                       # EOF

my $ls = runsub( 'ls',                   # Does nothing... yet
    {
        dir => '/tmp',
        out => \$output,
    }
);
$ls->( 'here' );                         # Runs in /tmp and puts
$ls->( '-l', 'there');                   # (long) output in $output

# Spawn a process for asynchronous interaction
my $proc = spawn( @cmd, { encoding => 'iso-8859-3' } );
while ( my $line = $proc->stdout->getline ) {
    $proc->stdin->print("thanks\n");
}
warn $proc->stderr->getlines;

$proc->close();    # Finished talking to file handles
$proc->wait_child && die "Non-zero exit!: " . $proc->exit;

DESCRIPTION

Sys::Cmd lets you run a system command and capture its output, or spawn and interact with a system process through its stdin, stdout and error handles.

It provides the following advantages over Perl's builtin "system", "qx//", "fork"+"exec", and "open" functions for dealing with external processes:

  • Command lookups using File::Which (run, spawn)

  • Efficient process spawning with Proc::FastSpawn (run, spawn)

  • Warn on error output (run)

  • Raise exception on failure (run)

  • Capture output and error separately (run, spawn)

  • Asynchronous interaction through file handles (spawn)

  • Sensible exit values (spawn)

  • Template functions for repeated calls (runsub, spawnsub)

COMMAND PROCESSING

All functions take a @cmd list that specifies the command and its (standard) arguments. The first element of @cmd determines what/how things are run:

  • If it has one or more path components (absolute or relative) it is executed as with Proc::FastSpawn.

  • If it is a CODE reference (subroutine) then a fork is performed before running it in a child process. Unsupported on Win32.

  • Everything else is looked up using File::Which and the result is executed with Proc::FastSpawn.

The remaining scalar elements of @cmd are passed as arguments to the command (or subroutine).

OPTIONS

Sys::Cmd functions also take an optional \%opts HASH reference to adjust aspects of the execution.

The core functionality of Sys::Cmd is provided by the Sys::Cmd::Process class. The following configuration items (key => default) are common to all Sys::Cmd functions and are passed to the underlying objects at creation time:

dir => $PWD

The working directory the command will be run in. Note that if @cmd is a relative path, it may not be found from the new location.

encoding => $Encode::Locale::ENCODING_LOCALE

A string value identifying the encoding that applies to input/output file-handles, command arguments, and environment variables. Defaults to the 'locale' alias from Encode::Locale.

env => {}

A hashref containing key/values to be added to the current environment at run-time. If a key has an undefined value then the key is removed from the environment altogether.

input => undef

A scalar (string), or ARRAY reference, which is fed to the command via its standard input, which is then closed. An empty value ('') or empty list will close the command's standard input without printing. An undefined value (the default) leaves the handle open.

Some commands close their standard input on startup, which causes a SIGPIPE when trying to write to it, for which Sys::Cmd will warn.

on_exit

A subref to be called at the time that process termination is detected.

FUNCTIONS

The following functions are exportable from Sys::Cmd:

run( @cmd, [\%opt] ) => $output | @output

Executes @cmd and waits for the process to exit. Raises an exception in the event of non-zero exit value, otherwise warns for any errors received. In array context returns a list of lines instead of a scalar string. Accepts the following additional configuration keys:

out => undef

A reference to a scalar which is populated with output. When given run() returns nothing.

err => undef

A reference to a scalar which is populated with error output. When given run() does not warn of errors.

spawn( @cmd, [\%opt] ) => Sys::Cmd::Process

Returns a Sys::Cmd::Process object representing the process running @cmd. You can interrogate this and interact with the process via cmdline(), stdin(), stdout(), stderr(), close(), wait_child(), exit(), signal(), core(), etc.

Template Functions

When repeatedly calling a command, possibly with only slightly different arguments or environments, a kind of "templating" mechanism can be useful, to avoid repeating full configuration values and wearing a path lookup penalty each call.

The Sys::Cmd class itself provides this functionality, exposed as follows:

runsub( @cmd, [\%opt] ) => CODEref

Returns a subroutine reference representing a future command to be executed in the style of "run", with default arguments and options. When called, additional arguments and options are merged:

use Sys::Cmd 'runsub';
my $git = runsub(
    'git',
    {
        env => {
            GIT_AUTHOR_NAME  => 'Geekette',
            GIT_AUTHOR_EMAIL => 'xyz@example.com',
        }
    }
);

my @list   = $git->( 'add', 'file.txt' );
my $result = $git->( 'commit', 'HEAD',
    {
        env => {
            GIT_AUTHOR_NAME  => 'Override',
        }
    }
));

(Equivalent to manually calling syscmd(...) below, followed by the runsub method).

spawnsub( @cmd, [\%opt] ) => CODEref

Returns a subroutine reference representing a future process to be created in the style of "spawn", with default arguments and options. When called, additional arguments and options are merged.

use Sys::Cmd 'spawnsub';
my $cmd = spawnsub('command');
my @kids;
foreach my $i ( 0 .. 9 ) {
    $kids[$i] = $cmd->( 'arg', $i );
    $kids[$i]->stdin->print("Hello\n");
}
print $_->pid . ': ' . $_->stdout->getlines for @kids;
$_->wait_child for @kids;

(Equivalent to manually calling syscmd(...) below followed by the spawnsub method).

syscmd( @cmd, [\%opt] ) => Sys::Cmd

Returns a Sys::Cmd object representing a future command (or coderef) to be executed in some way. You can then call multiple run() or spawn() methods on the object for the actual work. The methods work the same way in terms of input, output, and return values as the exported package functions.

This function underlies the "runsub" and "spawnsub" functions, but the author finds it less attractive as an interface.

ALTERNATIVES

AnyEvent::Run, AnyEvent::Util, Argv, Capture::Tiny, Child, Forks::Super, IO::Pipe, IPC::Capture, IPC::Cmd, IPC::Command::Multiplex, IPC::Exe, IPC::Open3, IPC::Open3::Simple, IPC::Run, IPC::Run3, IPC::RunSession::Simple, IPC::ShellCmd, IPC::System::Simple, POE::Pipe::TwoWay, Proc::Background, Proc::Fork, Proc::FastSpawn, Spawn::Safe, System::Command

SUPPORT

This distribution is managed via github:

https://github.com/mlawren/p5-Sys-Cmd

This distribution follows the semantic versioning model:

http://semver.org/

Code is tidied up on Git commit using githook-perltidy:

http://github.com/mlawren/githook-perltidy

AUTHOR

Mark Lawrence <mark@rekudos.net>, based heavily on Git::Repository::Command by Philippe Bruhat (BooK).

COPYRIGHT AND LICENSE

Copyright 2011-2025 Mark Lawrence <nomad@null.net>

This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version.