No::Worries::Proc - process handling without worries
use No::Worries::Proc qw(proc_run proc_create proc_monitor proc_detach);
# simple interface to execute a command
$status = proc_run(command => [ "foo", "-x", 7 ]);
printf("foo exited with %d\n", $status);
# idem but with output redirection and more information
%proc = proc_run(command => [ qw(uname -a) ], stdout => \$output);
printf("process %d output is %s\n", $proc->{pid}, $output);
# start two process and wait for them to finish
$p1 = proc_create(
command => \@cmd1,
timeout => 5, # to be killed if still running after 5s
stderr => "/dev/null", # discard stderr
);
$p2 = proc_create(
command => \@cmd2,
stdout => \$output, # get stdout+stderr in $output
stderr => "", # merge stderr with stdout
);
proc_monitor([ $p1, $p2 ], timeout => 10);
printf("%d finished\n", $p1->{pid}) if $p1->{stop};
printf("%d finished\n", $p2->{pid}) if $p2->{stop};
# detach ourself to run as a daemon
proc_detach(callback => sub { print("started with pid $_[0]\n")});
This module eases process handling by providing high level functions to start,
monitor and stop processes. All the functions die() on error.
It also provides the
$No::Worries::Proc::Transient variable that
indicates, after a fork(), which process is transient and is about to
exec() or exit(). This is useful for instance in an END
block:
END {
# remove our pid file unless we are transient
pf_unset($pidfile) unless $No::Worries::Proc::Transient;
}
This module provides the following functions (none of them being exported by
default):
- proc_output(COMMAND...)
- execute the given command, capture its output (stdout only), check its
exit code (report an error if it is not zero) and return the captured
output; this is similar to Perl's qx() operator but bypassing the
shell and always checking the exit code
- proc_create(OPTIONS)
- create a new process that will execute the given command and return a hash
reference representing this process (see the "PROCESS STRUCTURE"
sections for more information), to be given to proc_monitor() or
proc_terminate() afterwards; supported options:
- "command": the command to execute, it
must be an array reference
- "cwd": the current working directory of
the new process
- "timeout": the maximum number of seconds
that the process is allowed to take to run (can be fractional); after
this, it may be killed by proc_monitor()
- "kill": how to "gently" kill
the process, see below
- "stdin": what to do with stdin, see
below
- "stdout": what to do with stdout, see
below
- "stderr": what to do with stderr, see
below
- proc_terminate(PROC[, OPTIONS])
- terminate the given process (PROC can be either a process structure or
simply a process id) by sending signals and waiting for the process to
finish; supported options:
- •
- "kill": how to "gently" kill
the process, see below
- proc_monitor(PROCS[, OPTIONS])
- monitor the given process(es) (as created by proc_create()); PROCS
can be either a single process or a reference to a list of processes;
supported options:
- "timeout": the maximum number of seconds
that proc_monitor() should take, can be fractional
- "bufsize": the buffer size to use for
I/O operations (default: 8192)
- "deaths": the minimum number of process
deaths that proc_monitor() will wait for before returning
- proc_run(OPTIONS)
- execute the given process (i.e. create and monitor it until termination)
and return its status (i.e. $?) in scalar context or the whole process
structure in list context; supported options: the ones of
proc_create()
- proc_detach([OPTIONS])
- detach the current process so that it becomes a daemon running in the
background (this implies forking and re-opening std*); supported
options:
- proc_status(STATUS)
- return a string representation of the given process status (i.e. $?)
- •
- "callback": code reference that will be
executed by the parent process just before exiting and will be given the
child pid
The process structure (hash) used in this module has the following fields:
- "command": the command being executed,
as an array reference
- "pid": the process id
- "start": the start time, in fractional
seconds
- "stop": the stop time, in fractional
seconds
- "status": the status (i.e. $?)
- "timeout": true if the process has been
killed because of timeout
When using the "stdin" option of
proc_create(), the value can be:
- a string: input will be read from the given file name
- a scalar reference: input will be the scalar itself
When using the "stdout" and
"stderr" options of proc_create(),
the value can be:
- a string: output will be written to the given file name
- a scalar reference: output will be stored in the scalar
- a code reference: each time new output is available, the code will be
called with two parameters: the process structure and the new output
In addition, "stderr" can also
be given an empty string that means that stderr should be merged with
stdout.
Both proc_create() and proc_terminate() can be given a
"kill" option that specifies how the process
should be killed.
The specification is a string containing a space separated list of
signal/grace couples, meaning: send the given signal and wait
a bit for the process to finish.
If not specified, the default is "TERM/1
INT/1 QUIT/1", meaning:
- send SIGTERM and wait up to 1 second for the process to finish
- if the process is still alive, send SIGINT and wait up to 1 second
- if the process is still alive, send SIGQUIT and wait up to 1 second
- if the process is still alive, send SIGKILL (implicit)
This module uses the following global variables (none of them being exported):
- $Transient
- true if the process is about to exec() or exit(), there is
usually no need to perform any cleanup (e.g. in an END block) for this
kind of process
Lionel Cons <http://cern.ch/lionel.cons>
Copyright (C) CERN 2012-2019