Skip to content

Instantly share code, notes, and snippets.

@riywo
Created March 21, 2011 15:49
Show Gist options
  • Save riywo/879661 to your computer and use it in GitHub Desktop.
Save riywo/879661 to your computer and use it in GitHub Desktop.
fork & exec with Perl
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>);
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>);
@riywo
Copy link
Author

riywo commented Mar 23, 2011

同じことをIPC::Runを使って書きなおしてみた。出力をすぐに取り出すためにはforkしてあげる必要がある。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment