Can the array version of the Perls system be used immediately?
Is it possible to use a version of the perls array system
(for example, a version that takes the first element as a command and the rest of the array as cmd arguments) and also create a new process with Linux so that the command system
returns immediately, for example to run a command, for example:
mycmd arg1 arg2 &
I tried using system( ('mycmd', 'arg1', 'arg2', '&') )
, but it just interprets the ampersand literally as the third argument.
I know I can just pass the entire command as a scalar in system
, but I'm just wondering if the array version can be used, because the parameters for that command will come from custom parameters in the CGI script.
source to share
The &
shell command part tells the shell to start the process in the background, so traversing the shell using the multi-arg form system
does not make sense.
Solution 1: Quote using String :: ShellQuote.
use String:ShellQuote qw( shell_quote );
system(shell_quote('mycmd', 'arg1', 'arg2').' &');
Solution 2: Quote using shell interpolation.
system('sh', '-c', '"$@" &', 'sh', 'mycmd', 'arg1', 'arg2');
Solution 3. Run the program in the background.
use IPC::Open3 qw( open3 );
{
open(local *CHILD_IN, '<', '/dev/null') or die $!;
local $SIG{CHLD} = 'IGNORE';
open3(
'<&CHILD_IN', '>&STDOUT', '>&STDERR',
'mycmd', 'arg1', 'arg2',
);
}
source to share
Since you have no interest in the fate of an executable program, you can use fork / exec. And you are running Linux, which allows you to use $SIG{CHLD} = 'IGNORE'
to avoid waiting for a child process.
sub background {
local $SIG{CHLD} = 'IGNORE';
# fork and then exec if we are the child
exec(@_) or die($!) unless fork;
}
background( 'mycmd', 'arg1', 'arg2' );
source to share