As esteemed moritz has suggested, this code is much cleaner, and includes diagnostics for the close. One thing to add; make sure that the last arg in the @arg array is '2>&1'. By default, the pipe operation of open (and shell) only sends stdout. If your application prints any information to stderr, it will be lost.
Erm, if you call open for a pipe with a list like that it behaves akin to system in that it doesn't run the arguments through a shell so that's not really going to do anything.
$perl -e 'open( my $x, "-|", "zsh", "-c", q{ctr=1;for i in "$@" ; do p
+rint "$ctr: $i"; ctr=$((ctr + 1)); done}, "--", qw(1 2 3 4), q{2>&1}
+); print while <$x>; close( $x ); print "\n"'
1: 1
2: 2
3: 3
4: 4
5: 2>&1
You are right -- I had forgotten about that. I think the only way to make the redirect work is to pass the command as libvenus originally specified, putting the '2>&1' right before the pipe.