首先,我知道这个问题被多次询问过,但是这里没有找到解决方案似乎对我有所帮助:/
我尝试在Perl中创建一个可以启动一些shell脚本的接口。
我的想法是获取shell脚本输出(stdout和stderr)并在我主窗口的另一帧上实时显示。
问题:
输出没有保存在变量中,它立即显示在屏幕中间,我不明白这种行为..
以下是结果的简短截图:
-deleted -
目标是在“进度”框架中显示输出;我尝试了很多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 @_;
}
}
或
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 );
}
感谢所有可以帮助我实现这一目标的Perl专家;)
编辑:
我找到了一种方法(感谢choroba的“stderr”线索):
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;
}
新结果的屏幕截图:
-deleted -
现在,我问为什么不评估shell脚本中的颜色:echo -ne [...]