我需要使用以下格式调用系统命令:
system( $cmd, @args );
当我将@args定义为
时my @args = ( "input1", "input2", ">", "file.out" );
“>”和“file.out”没有被解释为我希望的。如何将此形式的系统命令的输出发送到文件?
答案 0 :(得分:8)
将四个参数传递给程序,就像在shell中执行以下操作一样:
prog "input1" "input2" ">" "file.out"
如果不使用shell,则无法指示shell重定向输出!
以下解决方案假设:
my $prog = 'cat';
my @args = ( 'input1', 'input2' );
my $out_qfn = 'file.out';
以下解决方案都缺少一些错误检查。
使用shell执行重定向和转义。
system('/bin/sh', '-c', '"$@" > "$0"', $out_qfn, $prog, @args);
使用shell执行重定向,并使用Perl执行转义。
use String::ShellQuote qw( shell_quote );
my $cmd = shell_quote($prog, @args) . " >".shell_quote($out_qfn);
system('/bin/sh', '-c', $cmd);
最后一行简化为
system($cmd);
避免使用shell。使用Perl执行重定向。
# This isn't safe if @args is empty.
open(my $out_fh, '>', $out_qfn)
or die("Can't create output file \"$out_qfn\": $!\n");
open(my $pipe, '-|', $prog, @args)
or die $!;
while (<$pipe>) {
print($out_fh $_);
}
close($fh);
或
# This isn't safe if @args is empty.
use IPC::Open3 qw( open3 );
{
open(local *CHILD_STDIN, '<', '/dev/null')
or die $!;
open(local *CHILD_STDOUT, '>', $out_qfn)
or die("Can't create output file \"$out_qfn\": $!\n");
my $pid = open3('<&CHILD_STDIN', '>&CHILD_STDOUT', '>&STDERR', $prog, @args);
waitpid($pid, 0);
}
或
use IPC::Run3 qw( run3 );
run3([ $prog, @args ], \undef, $out_qfn);
或
use IPC::Run qw( run );
run([ $prog, @args ], \undef, $out_qfn);
答案 1 :(得分:0)
这是因为> file.out
是一个shell功能。按照您的方式使用system
- 您绕过shell,并将参数直接提供给您正在调用的程序。
请注意,参数处理因参数数量而异。如果LIST中有多个参数,或者LIST是具有多个值的数组,则使用列表其余部分给出的参数启动列表的第一个元素给出的程序。如果只有一个标量参数,则检查参数是否为shell元字符,如果有,则将整个参数传递给系统的命令shell进行解析(这是Unix平台上的/ bin / sh -c) ,但在其他平台上有所不同)。如果参数中没有shell元字符,则将其拆分为单词并直接传递给execvp,这样效率更高。在Windows上,只有系统PROGRAM LIST语法才能可靠地避免使用shell;系统LIST,即使有多个元素,如果第一个生成失败,也会回退到shell。
因此重定向不起作用 - 可能是您的程序忽略或以其他方式处理>
和file.out
传递的参数。
您可以选择一行&#34;系统&#34;:
system ( "$cmd @args" );
或者使用open
打开文件句柄,并在程序中执行IO。