是否可以使用perls system
命令的数组版本(即将第一个元素作为命令,将数组的其余部分作为cmd参数的版本),同时还使用Linux生成新进程以便system
命令立即返回,例如运行如下命令:
mycmd arg1 arg2 &
我尝试使用system( ('mycmd', 'arg1', 'arg2', '&') )
,但它只是将&符号解释为第三个参数。
我知道我可以将整个命令作为标量传递给system
,但我特别想知道是否可以使用数组版本,因为此命令的参数将来自CGI脚本中的用户选项。
答案 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' );