2015-01-04 16 views
1

我已成功运行Perl中的Tk GUI(Tkx模块)的外部命令,而不会阻止GUI在使用tkx :: open的同时检索stdout和stderr以运行外部命令

但是,我很难从stderr和stdout中检索消息:对于大多数命令,没有任何内容存储在变量$stdout$stderr中。

我在代码中缺少什么?

感谢

use Tkx; 
use strict; 
use Data::Dumper; 

my ($stdout,$stderr); 

my $mw = Tkx::widget->new("."); 
my $button=$mw->new_ttk__button(-text => "Run", -command => [\&run_command, "systeminfo"]); 
$button->g_grid(-column => 0, -row => 0); 
my $text = $mw->new_tk__text(-width => 32, -height => 16); 
$text->insert("end", "Test\n"); 
$text->g_grid(-column => 0, -row => 1); 

Tkx::MainLoop(); 
print "STDOUT: $stdout\n\n","-"x24,"\nSTDERR: $stderr\n"; 


sub run_command { 
    my $cmd = shift; 
    my $fh = Tkx::open("| $cmd", 'r') or die "$!"; 
    Tkx::fconfigure($fh, -blocking => 0); 
    $stdout.=Tkx::read($fh); 
    eval { Tkx::close($fh); }; 
    [email protected] if ([email protected]); 

} 

回答

0

在Linux上,我可以用Capture::Tiny得到一个外部命令的输出:

use strict; 
use warnings; 

use Capture::Tiny(); 
use Tkx; 

my ($stdout,$stderr); 

my $mw = Tkx::widget->new("."); 
my $button=$mw->new_ttk__button(-text => "Run", -command => [\&run_command, "echo aaa; eeee"]); 
$button->g_grid(-column => 0, -row => 0); 
my $text = $mw->new_tk__text(-width => 32, -height => 16); 
$text->insert("end", "Test\n"); 
$text->g_grid(-column => 0, -row => 1); 

Tkx::MainLoop(); 

sub run_command { 
    my $cmd = shift; 
    my ($stdout, $stderr, $exit) = Capture::Tiny::capture { 
     system($cmd); 
    }; 
    print "STDOUT: '$stdout'\n"; 
    print "STDERR: '$stderr'\n"; 
    print "Exit code: '$exit'\n"; 
} 

输出:

STDOUT: 'aaa 
' 
STDERR: 'sh: 1: eeee: not found 
' 
Exit code: '32512' 

编辑

为了避免挡住GUI,开发一个小包装脚本代替,例如:

$ cat wrapperl.pl 
use strict; 
use warnings; 
use Capture::Tiny; 

my $cmd = shift; 

my ($stdout, $stderr, $exit) = Capture::Tiny::capture { 
    system($cmd); 
}; 
print "Child is waiting..\n"; 
sleep 2; 
print "STDOUT: '$stdout'\n"; 
print "STDERR: '$stderr'\n"; 
print "Exit code: '$exit'\n"; 

然后使用:

sub run_command { 
    my $cmd = shift; 
    my $fh; 
    print "Master: calling command..\n"; 
    system ("wrapper.pl \"$cmd\" &"); 
    print "Master: returning to Tkx::Mainloop..\n"; 
} 

输出:

Master: calling command.. 
Master: returning to Tkx::Mainloop.. 
Child is waiting.. 
STDOUT: 'aaa 
' 
STDERR: 'sh: 1: eeee: not found 
' 
Exit code: '32512' 
+0

谢谢,这是一个非常有趣的建议。你会有另一种方法或一种方法来实现它不会阻止Tk GUI?谢谢 –

+0

@ Jean-FrancoisT。看到我更新的答案.. –

相关问题