-
Notifications
You must be signed in to change notification settings - Fork 2
mlawren/p5-Sys-Cmd
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
NAME Sys::Cmd - run a system command or spawn a system processes VERSION 0.99.1_2 (yyyy-mm-dd) SYNOPSIS use Sys::Cmd qw/run spawn/; # Simplest scenario: # - returns standard output # - warns about standard error # - raises exception on failure $output = run(@cmd); # Alternative input / output: # - returns standard output lines # - after feeding its standard input @output = run( @cmd, { input => 'food' } ); # More flexibility: # - Run in alternative directory # - With a modified environment # - Capturing stdout/stderr into variables run( @cmd, { dir => '/', env => { SECRET => $pass }, out => \$out, err => \$err, } ); # Spawn a process for asynchronous interaction # - Caller responsible for exec path, all input & output # - No exception raised on non-zero exit $proc = spawn( @cmd, { encoding => ':encoding(iso-8859-3)' },); while ( my $line = $proc->stdout->getline ) { $proc->stdin->print("thanks\n"); } my @errors = $proc->stderr->getlines; $proc->close(); # Finished talking to file handles $proc->wait_child(); # Cleanup # read process termination information $proc->exit(); # exit status $proc->signal(); # signal $proc->core(); # core dumped? (boolean) DESCRIPTION Sys::Cmd lets you run system commands and capture their output, or spawn and interact with a system process through its "STDIN", "STDOUT", and "STDERR" file handles. It also provides mock process support, where the caller defines their own outputs and error values. Log::Any is used for logging. The following functions are exported on demand: run( @cmd, [\%opt] ) => $output | @output Execute @cmd and return what the command sends to its "STDOUT", raising an exception in the event of non-zero exit value. In array context returns a list of lines instead of a scalar string. The first element of @cmd determines what/how things are run: * If it has a path component (absolute or relative) it is executed as is, using Proc::Spawn. * If it is a CODE reference (subroutine) then the funtion forks 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::Spawn. The optional "\%opts" hashref lets you modify the execution via the following configuration keys (=> default): 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 => ':utf8' An string value identifying the encoding of the input/output file-handles, passed to "binmode". Defaults to ':utf8'. 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 A string which is fed to the command via its standard input, which is then closed. An empty value will close the command's standard input immediately. An undefined value (the default) leaves it open until the command terminates. Some commands close their standard input on startup, which causes a SIGPIPE when trying to write to it, for which Sys::Cmd will warn. mock A subroutine reference which runs instead of the actual command, which provides the fake outputs and exit values. See "MOCKING" below for details. out A reference to a scalar which is populated with output. When used, "run()" returns nothing. err A reference to a scalar which is populated with error output. When used, "run()" does not warn of errors. on_exit A subref to be called at the time that process termination is detected. spawn( @cmd, [\%opt] ) => Sys::Cmd::Process Executes @cmd, similarly to "run()" above, but without any input handling, output collection, or process waiting; the "\%opt" keys "input", "out" and "err" keys are *invalid* for this function. This returns a (Sys::Cmd::Process) object representing the running process, which has the following methods: cmdline() => @list | $str In array context returns a list of the command and its arguments. In scalar context returns a string of the command and its arguments joined together by spaces. close() Close all filehandles to the child process. Note that file handles will automaticaly be closed when the Sys::Cmd object is destroyed. Annoyingly, this means that in the following example $fh will be closed when you tried to use it: my $fh = Sys::Cmd->new( %args )->stdout; So you have to keep track of the Sys::Cmd object manually. pid() The command's process ID. stderr() The command's *STDERR* file handle, based on IO::Handle so you can call getline() etc methods on it. stdin() The command's *STDIN* file handle, based on IO::Handle so you can call print() etc methods on it. Autoflush is automatically enabled on this handle. stdout() The command's *STDOUT* file handle, based on IO::Handle so you can call getline() etc methods on it. wait_child() -> $exit_value Wait for the child to exit using waitpid <http://perldoc.perl.org/functions/waitpid.html>, collect the exit status and return it. This method sets the *exit*, *signal* and *core* attributes and is called automatically when the Sys::Cmd::Process object is destroyed. After "wait_child" has been called the following are also valid: core() A boolean indicating the process core was dumped. exit() The command's exit value, shifted by 8 (see "perldoc -f system"). signal() The signal number (if any) that terminated the command, bitwise-added with 127 (see "perldoc -f system"). syscmd( @cmd, [\%opt] ) => Sys::Cmd When calling a command multiple times, possibly with different arguments or environments, a kind of "templating" mechanism can be useful, to avoid repeatedly specifying configuration values and wearing a path lookup penalty each call. A Sys::Cmd object represents a command (or coderef) *to be* executed, which you can create with the "syscmd" function: my $git = syscmd('git', env => { GIT_AUTHOR_NAME => 'Geekette', GIT_AUTHOR_EMAIL => '[email protected]', } ); You can then repeatedly call "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. However, additional arguments and options are *merged*: my @list = $git->run('ls-files'); # $PWD my $commit = $git->run( 'commit', { env => { GIT_AUTHOR_NAME => 'Sysgeek' } }); For even less syntax you can use the "runsub" or "spawnsub" methods to get a subroutine you can call directly: my $git = syscmd('git')->runsub; my @list = $git->('ls-files'); my $commit = $git->('show'); runsub( @cmd, [\%opt] ) => CODEref Equivalent to manually calling "syscmd(...)" followed by the "runsub" method. #!perl use Sys::Cmd 'runsub'; my $ls = runsub('ls'); $ls->('here'); $ls->('there'); spawnsub( @cmd, [\%opt] ) => CODEref Equivalent to manually calling "syscmd(...)" followed by the "spawnsub" method. #!perl use Sys::Cmd 'spawnsub'; my $spawn = spawnsub('command'); foreach my $i (0..9) { my $proc = $spawn->('arg', $i); $proc->stdin->print("Hello\n"); print $proc->stdout->getlines; $proc->wait_child } MOCKING The "mock" subroutine, when given, runs instead of the command line process. It is passed the Sys::Cmd::Process object as its first argument, which gives it access to the cmdline, dir, env, encoding, attributes as methods. run( 'junk', { input => 'food', mock => sub { my $proc = shift; my $input = shift; [ $proc->cmdline . ":Thanks for $input!\n", '', 0 ]; } } ); It is required to return an ARRAY reference (possibly empty), with the following elements: [ "standard output\n", # default '' "standard error\n", # default '' $exit, # default 0 $signal, # default 0 $core, # default 0 ] Those values are then returned from "run" as usual. At present this feature is not useful for interactive (i.e. spawned) use, as it does not dynamically respond to calls to "$proc-"stdin->print()>. 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::Spawn, 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 <[email protected]>, based heavily on Git::Repository::Command by Philippe Bruhat (BooK). COPYRIGHT AND LICENSE Copyright 2011-2025 Mark Lawrence <[email protected]> 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.