我对 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 进程上,并在正在运行的 bash 终端中打印该 strace 的输出,以确保它异步读取输出。
问题之一是我通过 ERROR 文件句柄获取输出。我对为什么会发生这种情况有点困惑。我是否对 open3 使用了正确的顺序,如果出现错误,为什么正确的输出甚至会输出到 stderr?
我遇到的第二个问题是我只有在 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";