在Perl中正确捕获shell脚本输出
首先,我知道这个问题被问了很多次,但这里似乎找不到解决办法:/ 我尝试用Perl创建一个接口,可以启动一些shell脚本 我的想法是获得shell脚本输出(stdout和stderr),并在主窗口的另一个框架上实时显示它 问题是: 输出没有保存在变量中,它会立即显示在屏幕中间,我不理解这种行为 下面是结果的一个小屏幕截图: -删除- 目标是在“进度”框架中显示输出;我尝试了许多Perl方法来实现这一点,但每次都失败了 以下是我尝试的一些例子:在Perl中正确捕获shell脚本输出,perl,shell,output,Perl,Shell,Output,首先,我知道这个问题被问了很多次,但这里似乎找不到解决办法:/ 我尝试用Perl创建一个接口,可以启动一些shell脚本 我的想法是获得shell脚本输出(stdout和stderr),并在主窗口的另一个框架上实时显示它 问题是: 输出没有保存在变量中,它会立即显示在屏幕中间,我不理解这种行为 下面是结果的一个小屏幕截图: -删除- 目标是在“进度”框架中显示输出;我尝试了许多Perl方法来实现这一点,但每次都失败了 以下是我尝试的一些例子: sub launch_child(@) {
sub launch_child(@)
{
my $pid = open(KID, '-|');
die "fork: $!" unless defined($pid);
if($pid) {
my $output;
while (<KID>) {
$process_tracking->text($process_tracking->text() . "$_");
}
close(KID);
} else {
exec @_;
}
}
新结果的屏幕截图:
-删除-
现在,我在问为什么shell脚本中的颜色没有被计算:
echo-ne[…]
您正确地读取了进程的标准输出,但是标准输出可以自由地直接进入屏幕。有关详细信息,请参阅。不确定要执行什么操作。。。但我尝试在STDOUT中重定向STDERR,它可以工作,但似乎在写入任何内容之前填充了缓冲区;我写了“$|=1”,但它没有改变任何东西:/@Doubidou:你说的“填充缓冲区”是什么意思?我的意思是,它要等到所有的shell脚本都执行完毕后才能显示任何内容;但就在一秒钟前,我发现了一个方法,通过在IO:Select中发送$fh,并执行一个单独的循环来读取Select;它的作品:)丑陋,但它的作品。。。现在我必须找到为什么我的shell脚本的ANSI颜色没有在Perl脚本中计算。。
sub launch_child()
{
my $sel = IO::Select->new();
open my $fh, '-|', './shell_script.sh';
while (<$fh>) {
$process_tracking->text($process_tracking->text() . "$_" );
}
close $fh;
$sel->add($fh);
push( @selects , $sel );
}
my @selects = ();
sub launch_child()
{
my $sel = IO::Select->new();
open my $fh, '-|', './shell_script.sh 2>&1';
$sel->add($fh);
push( @selects , $sel );
}
sub read_from_child()
{
if (scalar @selects > 0) {
for my $sel (@selects) {
if (my @readers = $sel->can_read(0)) {
for my $fh (@readers) {
my $rv = sysread($fh, my $buf, 64*1024);
if (!$rv) {
$sel->remove($fh);
close($fh);
next;
}
$process_tracking->text($process_tracking->text().$buf);
$process_tracking->cursor_to_end();
}
}
}
}
}
while (1) {
$cui->{-read_timeout} = 0;
$cui->do_one_event();
read_from_child();
sleep 0.1;
}