ケアすべきこと
標準出力を雑に取りたい時に便利。標準出力を補足し、出力は出さない。パイプとかリダイレクトとかできる。(shell経由になる)
$out = `perl -E 'say "Hello"'`;
$out = qx{perl -E 'warn "Hello\n"' 2>&1};
$exit = $? >> 8;
配列を渡すことでshell経由にならない。出力はそのまま。
my $ret = system('perl', '-E', 'say "Hello"');
# $ret には $? と同じ値が入ってくる
if ($ret != 0) {
}
if ($? == -1) {
print "failed to execute: $!\n";
}
elsif ($? & 127) {
printf "child died with signal %d, %s coredump\n",
($? & 127), ($? & 128) ? 'with' : 'without';
}
else {
printf "child exited with value %d\n", $? >> 8;
}
IPC::Cmd was first released with perl v5.9.5
標準モジュール!
use IPC::Cmd qw/run/;
my ($ok, $err, $full_buf, $stdout_buf, $sederr_buf) = run('perl', '-E', 'say "Hello"');
お手軽
open(STDOUT, '| tee "' . $tmpfile . '"');
open(STDERR, ">&STDOUT");
system('...');
pipe my $logrh, my $logwh or die "failed to create pipe:$!";
unless (my $pid = fork) {
if (defined $pid) {
# child process
close $logrh;
open STDERR, '>&', $logwh or die "failed to redirect STDERR to logfile";
open STDOUT, '>&', $logwh or die "failed to redirect STDOUT to logfile";
close $logwh;
exec 'perl', '-E', '....'; ## ここでコマンド実行
die "exec(2) failed:$!";
}
else {
close $logrh;
close $logwh;
warn "fork(2) failed:$!\n" unless defined $pid;
}
}
else {
close $logwh;
my $buf = '';
$buf .= $_ while <$logrh>;
close $logrh;
}
use PerlIO::Util;
open my $fh, ...;
$fh->push_layer(tee => *STDOUT);
$fh->push_layer(tee => \$out);
my ($stdout, $stderr) = tee {
...
};