1

我遇到了与天气研究预测 (WRF) 模型配置相关的 Perl 脚本问题。有问题的脚本是此处下载的一部分(需要登录,简单注册)。如果你下载的是最新的 WRF-NMM 内核,解压后的目录是 arch/Config_new.pl。我遇到的错误位于第 262-303 行的某处:

until ( $validresponse ) {
  print "------------------------------------------------------------------------\n" ;
  print "Please select from among the following supported platforms.\n\n" ;

  $opt = 1 ;
  open CONFIGURE_DEFAULTS, "< ./arch/configure_new.defaults" 
      or die "Cannot open ./arch/configure_new.defaults for reading" ;
  while ( <CONFIGURE_DEFAULTS> )
  {
    for $paropt ( @platforms )
    {
      if ( substr( $_, 0, 5 ) eq "#ARCH"
          && ( index( $_, $sw_os ) >= 0 ) && ( index( $_, $sw_mach ) >= 0 ) 
          && ( index($_, $paropt) >= 0 ) )
      {
        $optstr[$opt] = substr($_,6) ;
        $optstr[$opt] =~ s/^[   ]*// ;
        $optstr[$opt] =~ s/#.*$//g ;
        chomp($optstr[$opt]) ;
        $optstr[$opt] = $optstr[$opt]." (".$paropt.")" ;
        if ( substr( $optstr[$opt], 0,4 ) ne "NULL" )
        {
          print "  %2d.  %s\n",$opt,$optstr[$opt] ;
          $opt++ ;
        }
      }
    }
  }
  close CONFIGURE_DEFAULTS ;

  $opt -- ;

  print "\nEnter selection [%d-%d] : ",1,$opt ;
  $response = <STDIN> ;

  if ( $response == -1 ) { exit ; }

  if ( $response >= 1 && $response <= $opt ) 
  { $validresponse = 1 ; }
  else
  { print("\nInvalid response (%d)\n",$response);}
}

具体来说,我被发送到输入行,没有任何提示或我的选项列表。只有在我选择了一个有效的选项后,我才会看到之前的选项。这将再次重复第二次,并在更下方的另一段代码(第 478-528 行)。让我感到困惑的是,当我进入调试模式时,我在这部分代码的开始之前插入了一个中断。我跑了p $validresponse,得到以下信息:

0


If you REALLY want Grib2 output from WRF, modify the arch/Config_new.pl script.
Right now you are not getting the Jasper lib, from the environment, compiled into WRF.

这让我很感兴趣,因为这一段来自printf之前的几行。在这个特定的脚本中,它是迄今为止唯一运行的 printf,但是为什么将输出保存到下一个创建的变量中却是我无法理解的。有什么建议么?

编辑:查看 choroba 的建议后,任何类型的重定向都会出现同样的问题,无论是管道、使用tee还是 stderr/stdout 重定向。因此,我认为这可能是 bash 的问题?也就是说,我可以运行它的唯一方法是没有任何类型的日志记录(至少据我所知,这是非常有限的)。

4

2 回答 2

1

您希望启用自动刷新,以便在打印某些内容后自动刷新 Perl 打印缓冲区。这是 Perl 脚本输出到终端窗口时的默认行为,但是当输出以任何方式重定向时,默认是缓冲输出。启用自动刷新会禁用缓冲。

您可以通过将以下两行添加到 Perl 脚本的顶部(当然是在 Perl hashbang 行下方)来启用自动刷新:

use IO::Handle qw();
STDOUT->autoflush(1);
于 2012-06-19T20:20:08.113 回答
0

当您使用管道或类似的重定向时,您(通常)重定向 STDOUT。所有的打印语句都转到 STDOUT,因此在重定向时将发送到您要传送到的任何进程。如果没有看到您正在使用的完整命令,我无法确切说明为什么您没有看到 STDOUT 消息,但它们显然被重定向所吞噬。如果由您决定,这是否真的是一个问题。

线

$response = <STDIN> ;

导致脚本等待来自 STDIN 的输入,这就是您看到提示的原因。您没有向 STDIN 输入任何内容,因此它会等待。

于 2012-06-07T07:29:54.340 回答