Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Perl中正确捕获shell脚本输出_Perl_Shell_Output - Fatal编程技术网

在Perl中正确捕获shell脚本输出

在Perl中正确捕获shell脚本输出,perl,shell,output,Perl,Shell,Output,首先,我知道这个问题被问了很多次,但这里似乎找不到解决办法:/ 我尝试用Perl创建一个接口,可以启动一些shell脚本 我的想法是获得shell脚本输出(stdout和stderr),并在主窗口的另一个框架上实时显示它 问题是: 输出没有保存在变量中,它会立即显示在屏幕中间,我不理解这种行为 下面是结果的一个小屏幕截图: -删除- 目标是在“进度”框架中显示输出;我尝试了许多Perl方法来实现这一点,但每次都失败了 以下是我尝试的一些例子: sub launch_child(@) {

首先,我知道这个问题被问了很多次,但这里似乎找不到解决办法:/

我尝试用Perl创建一个接口,可以启动一些shell脚本

我的想法是获得shell脚本输出(stdout和stderr),并在主窗口的另一个框架上实时显示它

问题是:

输出没有保存在变量中,它会立即显示在屏幕中间,我不理解这种行为

下面是结果的一个小屏幕截图:

-删除-

目标是在“进度”框架中显示输出;我尝试了许多Perl方法来实现这一点,但每次都失败了

以下是我尝试的一些例子:

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;
}