Perl脚本在打印信息之前提示输入

时间:2012-06-02 07:00:19

标签: perl bash shell

我遇到与天气研究预测(WRF)模型配置相关的Perl脚本的问题。有问题的脚本是位于here的下载的一部分(需要登录,简单注册)。如果您下载最新的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的问题?也就是说,我可以运行它的唯一方法是没有任何记录(至少据我所知,这是公认的非常有限)。

2 个答案:

答案 0 :(得分:1)

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

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

use IO::Handle qw();
STDOUT->autoflush(1);

答案 1 :(得分:0)

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

$response = <STDIN> ;

导致脚本等待STDIN的输入,这就是你看到提示的原因。你没有把任何东西输送到STDIN所以它等待。