是否可以使用Perls系统函数的数组版本立即返回?

时间:2015-01-23 13:52:38

标签: linux perl

是否可以使用perls system命令的数组版本(即将第一个元素作为命令,将数组的其余部分作为cmd参数的版本),同时还使用Linux生成新进程以便system命令立即返回,例如运行如下命令:

mycmd arg1 arg2 &

我尝试使用system( ('mycmd', 'arg1', 'arg2', '&') ),但它只是将&符号解释为第三个参数。

我知道我可以将整个命令作为标量传递给system,但我特别想知道是否可以使用数组版本,因为此命令的参数将来自CGI脚本中的用户选项。

2 个答案:

答案 0 :(得分:5)

shell命令的&部分告诉shell在后台运行进程,因此使用{arg形式的system绕过shell是没有意义的。

解决方案1:使用String :: ShellQuote引用。

use String:ShellQuote qw( shell_quote );
system(shell_quote('mycmd', 'arg1', 'arg2').' &');

解决方案2:使用shell插值引用。

system('sh', '-c', '"$@" &', 'sh', 'mycmd', 'arg1', 'arg2');

解决方案3:自己在后台启动程序。

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

答案 1 :(得分:1)

由于你对执行程序的命运不感兴趣,你可以使用fork / exec。而你在Linux上允许使用$SIG{CHLD} = 'IGNORE'来避免等待子进程。

sub background { 
    local $SIG{CHLD} = 'IGNORE';
    # fork and then exec if we are the child
    exec(@_) or die($!) unless fork; 
}
background( 'mycmd', 'arg1', 'arg2' );