in reply to avoiding shell escapes with exec()

When you have pipes and file redirection, using 'exec @array' is not straightforward. I wrote some code that may help get you started.

Update: and as for passing your args to exec, it depends on how you would normally run tetheral on the command line. If you would normall run:

command arg1 arg2 "Quoted stuff as arg3"
Then you would pass to system or exec:
system('command', 'arg1', 'arg2', 'Quoted stuff as arg3');

Replies are listed 'Best First'.
Re^2: avoiding shell escapes with exec()
by chunter (Initiate) on Jun 27, 2007 at 18:44 UTC
    thanks, that worked! the only issue is that @pids doesn't seem to be globally referenced, so even though it gets populated with the child pids, the other fork of the program (that is watching to see if they hang) sees that array as empty. So I just had to export them to a file and then read them in when the timeout happened.
      ...the only issue is that @pids doesn't seem to be globally referenced...
      I'm not sure what you mean by that. This seems to work:
      my ($fh, @pids) = pipeline( [qw(ls -1)], [qw(sed -e s/t/a/g)], [qw(sed -e s/z/b/g)], # Let's "hang" for 20 seconds [qw(sleep 20)], ); eval { local $SIG{ALRM} = sub { die "alarm\n" }; # Assume we're "hung" after 5 seconds alarm 5; while (<$fh>) { print "$.:$_"; } }; if ($@) { die unless $@ eq "alarm\n"; # Kill the sleep process kill 1, $pids[0]; # timed out } else { close $fh; } print "Pids: @pids\n";
      Sorry if I'm misunderstanding, but glad you got it working.