in reply to Taming multiple external processes
Here's some code that will let you get the PID of each step in the pipeline. To avoid running a shell, pass each argument as a seperate parameter to pipeline.
pipeline takes as its first parameter the filehandle where the command's standard input should come from, and the rest of the parameters are the command to run. It returns a 2-element list, with the PID and output filehandle of the command. With your example, you'd do something like:
my($app1_pid,$app1_out)=pipeline(STDIN,'app1',$URL); my($app2_pid,$app2_out)=pipeline($app1_out,'app2'); while (<$app2_out>) { ... }
Here's the pipeline code, and a short example that runs sort |uniq -c |sort -rn. It's only tested slightly, so it may need some tweaking.
#!/usr/bin/perl use POSIX; my($pid1,$outfh1)=pipeline(STDIN,"sort"); my($pid2,$outfh2)=pipeline($outfh1,"uniq -c"); my($pid3,$outfh3)=pipeline($outfh2,"sort -rn"); warn "sort pid: $pid1\n"; warn "uniq pid: $pid2\n"; warn "sort2 pid: $pid3\n"; while (<$outfh3>) { print; } sub pipeline { my($in,@cmd)=@_; my($out,$child_write); pipe($out,$child_write) or die "pipe error: $!\n"; my $pid = fork; if (!defined($pid)) { die "fork error: $!\n" }; if ($pid) { # Parent close($child_write); return($pid,$out); } else { # child close($out); if (fileno($in) != 0) { close(STDIN) or die "Couldn't close STDIN: $!\n"; POSIX::dup2(fileno($in),0) or die "Couldn't dup to stdin: $!\n"; } close(STDOUT); POSIX::dup2(fileno($child_write),1) or die "Couldn't dup to stdout: $!\n"; exec(@cmd) or die "exec error: $!\n"; } }
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
We have a winner!
by 87C751 (Acolyte) on Jan 02, 2004 at 21:06 UTC |