That passes four arguments to the program, as if you executed the following in the shell:
prog "input1" "input2" ">" "file.out"
You can't instruct the shell to redirect output without using a shell!
The following solutions assume:
my $prog = 'cat';
my @args = ( 'input1', 'input2' );
my $out_qfn = 'file.out';
The following solutions are all lacking some error checking.
Solution 1
Use the shell to perform the redirection and escaping.
system('/bin/sh', '-c', '"$@" > "$0"', $out_qfn, $prog, @args);
Solution 2
Use the shell to perform the redirection, and use Perl to perform the escaping.
use String::ShellQuote qw( shell_quote );
my $cmd = shell_quote($prog, @args) . " >".shell_quote($out_qfn);
system('/bin/sh', '-c', $cmd);
The last line simplifies to
system($cmd);
Solution 3
Avoid using a shell. Use Perl to perform the redirection.
# 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);
or
# 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);
}
or
use IPC::Run3 qw( run3 );
run3([ $prog, @args ], \undef, $out_qfn);
or
use IPC::Run qw( run );
run([ $prog, @args ], \undef, $out_qfn);