Promised::Command - Run a command
use Promised::Command;
$cmd = Promised::Command->new (['ls', '-a', '/']);
$cmd->run->then (sub {
return $cmd->wait;
})->then (sub {
my $result = $_[0];
if ($result->exit_code == 0) {
warn "done";
} else {
warn "failed";
}
});
The Promised::Command
class provides a Promise-returning command execution interface.
Following methods are available:
- $cmd = Promised::Command->new ($args)
-
Create a new command object. The argument must be an array reference containing a command (zeroth item) and zero or more arguments (first or later items).
- $promise = $cmd->run
-
Start the execution of the command. It returns a Promise, which is resolved with a result object when the execution is started.
This method cannot be invoked multiple times.
- $promise = $cmd->wait
-
Return a Promise, which is resolved with a result object once the execution of the command has finished.
This method can be invoked before the
run
's promise is resolved, but it must be invoked after therun
method is invoked. This method always returns the same promise.The promise is resolved with a result object whose
is_success
method returns true even when the exit code of the command is non-zero. Note also that failure to execute the command (e.g. command-not-found error) is also result in resolving the promise with a successful result object whose exit code is non-zero.If the command has terminated by an uncaught signal, the promise is rejected with a result object whose
is_error
method returns true. - $boolean = $cmd->create_process_group
- $cmd->create_process_group ($boolean)
-
Get or set whether a new process group should be created for the command (by
setpgrp
) or not.This method must be invoked before the
run
method is invoked. If this method is not invoked, the same process group as the main process is used. - $cmd->wd ($string)
- $string = $cmd->wd
-
Get or set the current working directory for the command as a (system-dependent byte) string.
This method must be invoked before the
run
method is invoked. If this method is not invoked, the current directory is left unchanged (i.e. same as that of the main process). - $hashref = $cmd->envs
-
Return the environment variables for the command as a reference to the hash of environment name/value byte string pairs.
If a value is specified in the hash, an environment variable is set. Otherwise, if an
undef
value is explicitly specified in the hash, the environment variable, if any, is unset. Otherwise, any environment variable of the main process is left unchanged. This method must be invoked before therun
method is invoked. - $stream = $cmd->get_stdin_stream
- $cmd->stdin (SCALARREF)
-
Specify how the standard input is handled.
If the
get_stdin_stream
is invoked, a WritableStream object that is a writable stream of the input is returned. Any written value (i.e. the argument too thewrite
method of the writer) must be an ArrayBufferView (such as DataView and TypedArray::Uint8Array). If the stream is aborted, the input is closed as soon as possible (which means not all data might be written, though it does not affect the execution of the child process).If a scalar reference is specified to the
stdin
method, the referenced scalar value is written as the input. The referenced value must be a byte string.Only one of these methods must be invoked at most once. These methods must be invoked before the
run
method is invoked.If these methods are not invoked, the input's handling is left unchanged (i.e. same as the standard input of the main process).
- $stream = $cmd->get_stdout_stream
- $cmd->stdout (SCALARREF)
- $cmd->stdout (CODE)
- $stream = $cmd->get_stderr_stream
- $cmd->stderr (SCALARREF)
- $cmd->stderr (CODE)
-
Specify how the standard output or the standard error output is handled.
If the
get_stdout_stream
orget_stderr_stream
method is invoked, a ReadableStream object that is a readable byte stream of the output is returned. If the stream is canceled, any remaining data are silently discarded (which does not affect the child process).If a scalar reference is specified to the
stdout
orstderr
method, the output is set to the referenced scalar value.If a code reference is specified to the
stdout
orstderr
method, the code is invoked with a chunk as the argument whenever the chunk is available, and with anundef
as the argument when the end of the output is reached.Only one of these methods must be invoked at most once for each of standard output and standard error output. These methods must be invoked before the
run
method is invoked.If these methods are not invoked, the output's handling is left unchanged (i.e. same as the standard output or the standard error output of the main process).
- $pid = $cmd->pid
-
Return the process ID of the child process (i.e. the command's process).
This method can be invoked after the
run
promise is resolved. Note that there can no longer be the process with the ID or can be a different process with the ID if the command has finished. - $boolean = $cmd->running
-
Return whether the command is running or not.
Note that returning a true value does not mean the command is actually in active; it might be finished but not
waitpid
ed by this process yet. - $promise = $cmd->send_signal ($signal)
-
Send a signal to the command's process, if running.
The argument must be a string or integer representing the signal, such as
INT
or2
, or zero to not send any signal. Seeperldoc -f kill
.The method returns a Promise, which is resolved with a result object whose
killed
method returns the number of processed to which the signal is sent. If the command's process is no longer running, the signal is sent to no process. - $value = $cmd->propagate_signal
- $cmd->propagate_signal ($value)
-
Get or set whether signals to this (main) process should be propagated to the child (command) process or not.
The value can be a non-reference value or an array reference of signal names or an array reference of a pair of signal names. A non-reference value is equivalent to
['INT', 'QUIT', 'TERM']
. A pair of signal names represents that when the first signal is received by the main process, the second signal should be sent to the child process instead. The value represents the types of the signals to propagate. Signals specified by this method caught by the main process result in terminating the main process after the propagation.This method must be invoked before the
run
method is invoked. If this method is not invoked, no signal is propagated.If signals are to be propagated, any other signal handling should be done through Promised::Command::Signals to avoid confliction of signal handlers.
- $signal = $cmd->signal_before_destruction
- $cmd->signal_before_destruction ($signal)
-
Get or set the signal (e.g.
KILL
orTERM
) which should be sent to the command (child) process if it is still running when the command object is destroyed (i.e. the $cmd object is destroyed without itswait
method invoked). This feature is useful when the command object can be discarded by unexpected shutdown of the application (e.g. Perl runtime error) but still need to ensure that child process should be terminated.This method must be invoked before the
run
method is invoked. If this method is not invoked, no signal is sent. - $seconds = $cmd->timeout
- $cmd->timeout ($seconds)
-
Get or set the timeout from the execution of the command in seconds. If a positive number is specified, the signal specified by the
timeout_signal
method is sent to the command's process, if any. Otherwise no timeout is set.This method must be invoked before the
run
method is invoked. - $signal = $cmd->timeout_signal
- $cmd->timeout_signal ($signal)
-
Get or set the signal (e.g.
KILL
orTERM
) which should be sent when thetimeout
seconds has elapsed before the command returns. It is set toTERM
unless explicitly specified.This method must be invoked before the
run
method is invoked. - $cmd->abort_signal ($asignal)
-
Set the abort signal (AbortSignal object from the https://github.com/wakaba/perl-promise respository; the value returned by the
$abort_controller->signal
method) which can be used to send a signal to terminate the process.The signal sent when aborted is specified by the
timeout_signal
method.This method must be invoked before the
run
method is invoked.
Promises are resolved with a result object, which has following methods:
- $boolean = $result->is_success
- $boolean = $result->is_error
-
Whether the operation has succeded or in error. Note that
!!$result->is_success == !!!$result->is_error
is always true. - $string = '' . $result
-
Return a short message of the result for the developer.
- $int = $result->exit_code
-
Return the exit code of the command, if applicable, or
-1
otherwise. - $int = $result->signal
-
Return the signal which terminates the command, if applicable.
- $boolean = $result->core_dump
-
Return whether there is a core dump or not, if applicable.
- $int = $result->killed
-
Return the number of process to which the signal is sent. Used by
send_signal
's promise. - $string = $result->message
-
Return a short error message for the developer, if available.
If the environment variable PROMISED_COMMAND_DEBUG
is set to a true value, debug messages are printed to the standard error output.
There are related modules: Promised::Command::Signals, Promised::Command::Docker.
The module requires Perl 5.10 or later.
The module requires Promise <https://github.com/wakaba/perl-promise> and AnyEvent::Util.
Methods get_stdin_stream
, get_stdout_stream
, and get_stderr_stream
require the ReadableStream module from the perl-streams repository <https://github.com/manakai/perl-streams>.
Wakaba <wakaba@suikawiki.org>.
This repository was located at <https://github.com/wakaba/perl-promised-command> until 2 February, 2022.
Copyright 2015-2022 Wakaba <wakaba@suikawiki.org>.
This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.