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.

0


source to share


2 answers


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',
   );
}

      

+5


source


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' );

      

+1


source







All Articles