【问题标题】:Dynamically capture output of system command in Perl在 Perl 中动态捕获系统命令的输出
【发布时间】:2015-06-30 09:04:36
【问题描述】:

在我的 Perl 代码中,我使用系统命令来运行脚本。我正在使用 Gtk2::Perl 和 Glade 来构建 UI。我需要将命令的输出不仅捕获到控制台(Capture::Tiny 确实如此),而且还捕获到我的 GUI 中的 TextView。

system("command");

$stdout = tee{                         #This captures the output to the console
system("command");  
};

$textbuffer->set_text($stdout);       #This does set the TextView with the captured output, but *after* the capture is over. 

任何帮助将不胜感激。

【问题讨论】:

  • 那么你遇到了什么问题?
  • 我需要在 TextView 中捕获 system 的输出,同时在控制台上捕获它。这不会发生。

标签: perl glade


【解决方案1】:

如果您尝试“捕获”system 调用的输出,那么我建议最好的方法是使用 open 并打开进程的文件句柄:

my $pid = open ( my $process_output, '-|', "command" ); 

然后您可以像读取文件句柄一样读取$process_output(请记住,如果没有等待处理的 IO,它会阻塞)。

while ( <$process_output> ) { 
   print; 
}

close ( $process_output ); 

您可以通过waitpid 系统调用“伪造”system 的行为:

 waitpid ( $pid, 0 ); 

这将“阻塞”您的主程序,直到系统调用完成。

【讨论】:

  • 谢谢。我想使用open 是我最好的选择。会这样做!
  • 这非常有用,但实际上并不能真正解决我的问题 - 输出在生成时不会在 TextView 中动态更新。很遗憾,有明显的延迟。
  • 在 IO::handle 文档中查找 autoflush。像这样打开已经在并行进程中运行了。
【解决方案2】:

system() 无法实现您想要做的事情。 System() fork 一个新进程等待它终止。然后你的程序继续(见manual)。您可以启动一个子流程(执行 system() 为您执行的任何操作)并读取此子流程的标准输出。例如,您可以在这里获得灵感:redirecting stdin/stdout from exec'ed process to pipe in Perl

【讨论】:

  • 啊,我明白了。我希望能够用 system() 做一些事情,因为这个捕获是唯一缺少的东西。非常感谢!
猜你喜欢
  • 1970-01-01
  • 2014-08-16
  • 1970-01-01
  • 2016-07-03
  • 1970-01-01
  • 2010-09-09
  • 2011-03-15
  • 2012-05-14
  • 2014-01-27
相关资源
最近更新 更多