私は perl プログラミングに比較的慣れていないので、open3 がどのように機能するかを理解しようとしています。これがコードです。
#!/usr/bin/perl
use strict;
use warnings;
use IPC::Open3;
my $dir = "/home/vman/Documents/Dev/perl_scripts/Provenance/temp";
my $fileHandle;
my $bashPid;
print "Starting main program\n";
my $pid = fork();
if($pid)#Parent process2
{
print("Start transfer.\n");
$bashPid = $pid;
#Attaching an strace to the executed command which happens in the child process
open3(\*WRITE, \*READ,\*ERROR,"strace", "-f", "-F", "-e", "trace=open,execve","-p", $bashPid, "-s", "2097152","-q");
while(<READ>)
{
print("Here1\n");
print("$_");
}
while(<ERROR>)
{
print("$_");
}
print("Finish transfer.\n");
}
elsif($pid == 0)
{
if (scalar(@ARGV == 0))
{
exit
}
my $args = join(' ', @ARGV);
exec($args);
}
else
{
die("Could not fork.");
}
close(READ);
close(WRITE);
close(ERROR);
waitpid($bashPid, 0);
print "End of main program\n";
bash プロセスで strace を実行し、出力中にすべての出力をキャプチャしたいと考えています。次に、その出力を取得して解析し、どのファイルがどのプロセスによって変更されているかを確認し、それらの変更を mysql データベースに保存します。今のところ、私がやろうとしているのは、strace を既存の bash プロセスにアタッチし、その strace の出力を実行中の bash ターミナル内に出力して、非同期で出力を読み取っていることを確認することだけです。
問題の 1 つは、エラー ファイルハンドルを介して出力を取得していることです。なぜこれが起こっているのか、少し混乱しています。open3 に正しい順序を使用していますか? エラーがある場合、正しい出力が stderr に出力されるのはなぜですか?
私が抱えている2番目の問題は、execの実行中に実行する必要があるため、execが終了したときにのみ出力を取得していることです。open3 は非同期で実行されると思いました。
提案どおり、これは私がやったことであり、完全に機能します。
#!/usr/bin/perl
use strict;
use warnings;
use IPC::Run3;
my $bashPid;
print "Starting main program\n";
my $pid = fork();
if($pid)#Parent process
{
print("Start transfer.\n");
$bashPid = $pid;
#Attaching an strace to the executed command which happens in the child process
my $command = "strace -fFe trace=open,execve -p $bashPid -s 2097152 -q";
run3($command, \*STDIN, \*STDOUT, \*STDERR);
if ($?)
{
die "something went horribly wrong";
}
while(<STDERR>)
{
print($_);
}
print("Finish transfer.\n");
}
elsif($pid == 0)#cild process
{
if (scalar(@ARGV == 0))
{
exit
}
my $args = join(' ', @ARGV);
exec($args);
}
else
{
die("Could not fork.");
}
close(STDIN);
close(STDOUT);
close(STDERR);
waitpid($bashPid, 0);
print "End of main program\n";