Created
March 21, 2011 15:49
-
-
Save riywo/879661 to your computer and use it in GitHub Desktop.
fork & exec with Perl
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use strict; | |
use warnings; | |
use IO::Handle; | |
sub fork_exec { | |
my @args = @_; | |
my $handles = []; | |
if (ref($args[$#args]) eq 'GLOB') { | |
my $stdin = pop @args; | |
push @{$handles}, { | |
'read' => $stdin, | |
'write' => undef, | |
}; | |
} | |
else { | |
push @{$handles}, _make_pipe(); | |
} | |
my $pid; | |
for (my $i=0; $i<=$#args; $i++) { | |
push @{$handles}, _make_pipe(); | |
if ($pid = fork) { | |
close $handles->[$i+1]->{'write'}; | |
close $handles->[$i]->{'read'}; | |
} | |
else { | |
close $handles->[0]->{'write'} if($handles->[0]->{'write'}); | |
close $handles->[$i+1]->{'read'}; | |
open STDOUT, '>&', $handles->[$i+1]->{'write'}; | |
open STDIN, '<&', $handles->[$i]->{'read'}; | |
exec @{$args[$i]}; | |
} | |
} | |
return ($pid, $handles->[scalar(@{$handles})-1]->{'read'}); | |
} | |
sub _make_pipe { | |
my ($read, $write); | |
pipe $read, $write; | |
$write->autoflush(1); | |
return { | |
'read' => $read, | |
'write' => $write, | |
}; | |
} | |
__END__ | |
my ($pid, $stdout) = fork_exec(['iostat', '1', '3'], ['cat', '-nu']); | |
my ($pid2, $stdout2) = fork_exec(['cat', '-nu'], ['cat', '-nu'], $stdout); | |
print while(<$stdout2>); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use strict; | |
use warnings; | |
use IO::Handle; | |
use IPC::Run qw(run); | |
sub fork_run { | |
my @args = @_; | |
my $stdin = \undef; | |
$stdin = pop @args if (ref($args[$#args]) eq 'GLOB'); | |
my ($stdout, $stdout_write); | |
pipe $stdout, $stdout_write; | |
$stdout_write->autoflush(1); | |
my $pid; | |
if ($pid = fork) { | |
close $stdout_write; | |
} | |
else { | |
close $stdout; | |
open STDOUT, '>&', $stdout_write; | |
my @run_args = (shift(@args), $stdin); | |
push @run_args, ('|', $_) for (@args); | |
run @run_args or die; | |
close $stdout_write; | |
exit; | |
} | |
return ($pid, $stdout); | |
} | |
__END__ | |
my ($pid, $stdout) = fork_run(['iostat', '1', '3'], ['cat', '-nu']); | |
my ($pid2, $stdout2) = fork_run(['cat', '-nu'], ['cat', '-nu'], $stdout); | |
print while(<$stdout2>); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
同じことをIPC::Runを使って書きなおしてみた。出力をすぐに取り出すためにはforkしてあげる必要がある。