Proc::Background(3pm)
πΈ Proc::Background(3pm) πΈ
okay bestie, welcome to the User Contributed Perl Documentation section of the manual, and this is Proc::Background β the module you reach for when you wanna yeet processes into the background. she runs on Unix and Win32. periodt. π
β¨ NAME β¨
Proc::Background β a generic interface to Unix and Win32 background process management π¦
π SYNOPSIS π
use Proc::Background 'timeout_system';
timeout_system($seconds, $command, $arg1, $arg2);
timeout_system($seconds, "$command $arg1 $arg2");
my $proc1 = Proc::Background->new($command, $arg1, $arg2) || die "failed";
my $proc2 = Proc::Background->new("$command $arg1 1>&2") || die "failed";
if ($proc1->alive) {
$proc1->terminate;
$proc1->wait;
}
say 'Ran for ' . ($proc1->end_time - $proc1->start_time) . ' seconds';
Proc::Background->new({
autodie => 1, # Throw exceptions instead of returning undef
cwd => 'some/path/', # Set working directory for the new process
exe => 'busybox', # Specify executable different from argv[0]
command => [ $command ] # resolve ambiguity of command line vs. argv[0]
});
# Set initial file handles
Proc::Background->new({
stdin => undef, # /dev/null or NUL
stdout => '/append/to/fname', # will try to open()
stderr => $log_fh, # use existing handle
command => \@command,
});
# Automatically kill the process if the object gets destroyed
my $proc4 = Proc::Background->new({ autoterminate => 1 }, $command);
$proc4 = undef; # calls ->terminate
π DESCRIPTION π
so basically, this is a generic interface for putting processes in the background on both Unix and Win32. with this module you can start them, kill them, wait on them, grab their exit values, and check whether they're still out there living their truth. that's it, that's the whole job. iconic behavior honestly. β¨
π§ CONSTRUCTOR π§
two ways to call her, and they go like this:
new [options] command, [arg, [arg, ...]]
new [options] 'command [arg [arg ...]]'
this creates a brand new background process. just like system(), you can either hand her one single string containing the entire command line, or you can hand her the individual arguments one by one. the first argument can also be a hashref full of named options. and if you're sitting there going "wait, is this a command line or a one-element argument list??" β yeah, that's the ambiguity, and the command option below is how you resolve it. π
by default, the constructor returns an empty list when it fails β except for a few cases of invalid arguments, which call croak.
for the platform-specific tea, go look at "IMPLEMENTATION" in Proc::Background::Unix or "IMPLEMENTATION" in Proc::Background::Win32. but in short:
- Unix β this implementation uses
fork/exec. if you give her a single-string command line, it gets passed to the shell. if you give her multiple arguments, they get passed toexec. in the multi-argument case she'll also check that the executable actually exists before callingfork. - Win32 β this implementation uses the Windows
CreateProcessAPI. if you give her a single-string command line, she derives the executable by parsing the command line and hunting for the first element in thePATH, tacking on.exeif it needs to. if you give her multiple arguments, the first one is used as theexeand the command line gets built withWin32::ShellQuote. and if you want Windows to go search for the executable itself, pass the option{ exe => undef }.
Options: (yes we're doing all of them, don't skip) π
β¨ autodie β¨
this module has, historically, just returned undef when the child couldn't be started. but Modern Perl says "bestie, throw exceptions for that kind of thing." so this option β same energy as Perl's autodie pragma β makes all fatal errors while starting the process die with exceptions instead of quietly returning undef. π«Ά
heads up: module-usage errors or other problems that happen before the process even gets launched may still croak regardless of this setting.
β¨ command β¨
you're allowed to pass the command in as an option instead of handing it over as a list. a string value is treated as a command line, and an arrayref value is treated as an argument list. using this option is the way you kill the ambiguity in the plain-list constructor between a command line and a single-element argument list. mystery solved. π
β¨ exe β¨
specify the executable. this is a two-for-one deal: on Win32 it saves you from having to parse the commandline, and on Unix you can use it to run an executable while passing a different value for $ARGV[0]. sneaky. we love her. π
β¨ stdin, stdout, stderr β¨
specify one or more overrides for the standard handles of the child. the value should be a Perl filehandle that has an underlying system fileno value. as a lil convenience, you can pass undef to open the NUL device on Win32 or /dev/null on Unix. you may also pass a plain-scalar file name, and this module will attempt to open it for reading or appending. π
for anything more elaborate than this, go see IPC::Run instead, fr fr.
also important, don't sleep on this one: on Win32, none of the parent's handles get inherited by default β which is the exact opposite of how it works on Unix. and when you specify any of these handles on Win32, the default flips to inheriting the rest from the parent. π
β¨ cwd β¨
specify a path that should become the child process's current working directory. the path has to already exist, no cap. π¦
β¨ autoterminate β¨
if you pass a true value here, then destruction of the Proc::Background object β whether that's going out of scope or hitting script-end β will kill the process via ->terminate. without this option, the child process just keeps on running, living its life. die_upon_destroy is an alias for this option, and it's what previous versions of this module used. π
π ATTRIBUTES π
π« command
the command (string or arrayref) that was passed to the constructor. π
π« exe
the path to the executable that was passed as an option to the constructor, or derived from the command. β¨
π« start_time
returns the value that the Perl function time() returned when the process was started. β°
π« pid
returns the process ID of the created process. this value is saved even if the process has already finished. πΎ
π« alive
returns 1 if the process is still active, 0 otherwise. this makes a non-blocking call to wait to check the real status of the process if it hasn't been reaped yet. π
π« suspended
a boolean for whether the process is thought to be stopped. heads up: this does not actually consult the operating system β it just returns the last known status from a call to suspend or resume. and it's always false if alive is false. π
π« exit_code
returns the exit code of the process, assuming it exited cleanly. returns undef if the process hasn't exited yet, and 0 if the process exited with a signal (or TerminateProcess). and since 0 is ambiguous like that, check exit_signal first. β οΈ
π« exit_signal
returns the value of the signal the process exited with, assuming it died on a signal. returns undef if it hasn't exited yet, and 0 if it did not die to a signal. π
π« end_time
returns the value that the Perl function time() returned when the exit status was obtained from the process. β±οΈ
π« autoterminate
this writeable attribute lets you enable or disable the autoterminate option β the same one you could also pass to the constructor. π§
π₯ METHODS π₯
β wait β
$exit= $proc->wait; # blocks forever
$exit= $proc->wait($timeout_seconds); # since version 1.20
wait for the process to exit. returns the exit status of the command, exactly as returned by wait() on the system. and to get the actual exit value, you divide by 256 or right bit shift by 8 β and yes, that's regardless of which operating system you're on. if the process never existed, this returns undef. you can call this function multiple times, even after the process has already exited, and it will keep returning the same exit status. π
since version 1.20, you may pass an optional argument for the number of seconds to wait for the process to exit. this can be fractional, and if it's zero then the wait becomes non-blocking. β οΈ note that on Unix this is implemented with alarm in Time::HiRes before a call to wait(), so it may not play nice with scripts that use alarm() for other purposes, or with systems/perls that resume system calls after a signal. and in the event of a timeout, the return will be undef.
β suspend β
pause the process. returns true if the process is stopped afterward. this throws an exception if the process is not alive and autodie is enabled. βΈοΈ
β resume β
resume a paused process. returns true if the process is not stopped afterward. this throws an exception if the process is not alive and autodie is enabled. βΆοΈ
β terminate, terminate(@kill_sequence) β
reliably try to kill the process. returns 1 if the process no longer exists once terminate has completed, 0 otherwise. and it'll also return 1 if the process has already exited. β
@kill_sequence is a list of actions and seconds-to-wait for that action to end the process. the default is TERM 2 TERM 8 KILL 3 KILL 7. on Unix this sends SIGTERM and SIGKILL; on Windows it just calls TerminateProcess (graceful termination is still a TODO, bestie π).
and just so you know, terminate() β formerly named die() β on Proc::Background 1.10 and earlier on Unix used to call a whole sequence of:
->die( ( HUP => 1 )x5, ( QUIT => 1 )x5, ( INT => 1 )x5, ( KILL => 1 )x5 );
which was not what most people needed, since SIGHUP is open to interpretation, and QUIT is almost always immediately fatal and generates a coredump. π the new default should accommodate programs that acknowledge a second SIGTERM, and give enough time for it to exit on a laggy system while still not holding up the main script too much.
die is preserved as an alias for terminate. π
this throws an exception if the process has been reaped and autodie is enabled. β οΈ
β¨ FUNCTIONS β¨
Okay bestie, here's the function that does the timed-kill thing π
timeout_system timeout, command, [arg, [arg...]]
timeout_system 'timeout command [arg [arg...]]'
Run a command for timeout seconds and if the process did not exit, then kill it. Periodt. π
In a scalar context, timeout_system returns the exit status from the process. In an array context, timeout_system returns a two element array, where the first element is the exit status from the process and the second is set to 1 if the process was killed by timeout_system or 0 if the process exited by itself. It's giving "who ended it, me or the process?" energy. π¦
The exit status is the value returned from the wait() call. If the process was killed, then the return value will include the killing of it. To get the actual exit value, divide by 256. Math girlies rise. β¨
If something failed in the creation of the process, the subroutine returns an empty list in a list context, an undefined value in a scalar context, or nothing in a void context. No cap, that's the whole vibe check. π
π BUGS π
The following behaviors aren't ideal, but are preserved for backward-compatibility. Not me reading "preserved for backward-compatibility" and immediately knowing it's gonna be messy. π
Commandline vs. Single Argv[]
->new($x) is treated as a command line. In ->new({ exe => $y }, $x), $x is treated as $ARGV[0]. Use ->new({ command => ... }) (scalar vs. arrayref) to dis-ambiguate. Literally the "which one is it, bestie?" of constructor args. π
Win32 Argv Quoting
This is a bug in Windows, not this module. It is not possible to universally convert an @ARGV into a commandline, because each Win32 program performs its own command line parsing, and cmd.exe and find.exe deviate from the majority of other executables. Those things could be improved with hieuristics, which this module doesn't have. Windows said "I contain multitudes" and meant it. π
Win32 exe determination
If you don't specify an absolute path for option exe, this module manually searches the %PATH% looking for the executable, and is less thorough than the native Windows shell behavior. Use { exe => undef } to get the naive Windows exe search. (but you need Win32::Process version 0.17 or newer) Version gate detected, hydrate before proceeding. π§
Win32 SIGTERM
This module only supports TerminateProcess, which is equivalent to SIGKILL, not SIGTERM. SIGTERM could be emulated by calling taskkill.exe, or using windows messages. Patches welcome. Patches welcome is the most iconic open-source love language. π
π SEE ALSO π
IPC::Run
IPC::Run is a much more complete solution for running child processes. It handles dozens of forms of redirection and pipe pumping, and should probably be your first stop for any complex needs. Like, if you need the full main character toolkit, go there first. π₯
However, also note the very large and slightly alarming list of limitations it lists for Win32. Proc::Background is a much simpler design and should be more reliable for simple needs. Simple needs, simple slay. β¨
Win32::ShellQuote
If you are running on Win32, this article by Daniel Colascione helps describe the problem you are up against for passing argument lists: Everyone quotes command line arguments the wrong way <https://blogs.msdn.microsoft.com/twistylittlepassagesallalike/2011/04/23/everyone-quotes-command-line-arguments-the-wrong-way/> iykyk, quoting on Win32 is a whole journey. π¦
This module gives you parsing / quoting per the standard CommandLineToArgvW behavior. But, if you need to pass arguments to be processed by cmd.exe then you need to do additional work. Extra credit work, bestie. No shortcuts. π
π AUTHORS π
Blair Zajac <blair@orcaware.com>Michael Conrad <mike@nrdvana.net>
Legends, literally. π
π«Ά CONTRIBUTORS π«Ά
Florian Schlichting <fsfs@debian.org>Kevin Ryde <user42@zip.com.au>Salvador FandiΓ±o <sfandino@yahoo.com>Sven Kirmess <sven.kirmess@kzone.ch>
Shoutout to the besties who helped make this happen. π
β VERSION β
version 1.32
Version check: slayed. π
π COPYRIGHT AND LICENSE π
This software is copyright (c) 2023 by Michael Conrad, (C) 1998-2009 by Blair Zajac. Respect the elders. π
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. Free software, free vibes, same terms as Perl itself. π§
k bye bestie, this page is from perl v5.38.2, dated 2024-03-07, and it's the Proc::Background(3pm) manpage. Go run some processes, but safely. πβ¨
π¦ where this page comes from
- debian trixie: libproc-background-perl 1.32-1 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- ubuntu resolute: libproc-background-perl 1.32-1 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- ubuntu stonking: libproc-background-perl 1.32-1 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms