Justin Joplin
Justin Joplin

Reputation: 11

Perl Script Prompts for Input before Printing Information

I'm having an issue with a Perl script relating to the Weather Research Forecast (WRF) model configuration. The script in question is a part of the download located here (login required, simple signup). If you download the most recent WRF-NMM core, in the unzipped directory is arch/Config_new.pl. The error that I'm having lies somewhere within lines 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);}
}

Specifically, I am sent to an input line without any kind of prompting or list of what my options are. Only after I select a valid choice am I presented with the previous options. This is repeated a second time with another chunk of code further down (lines 478-528). What's got me confused is that, when I entered debugging mode, I inserted a break before the start of this portion of code. I ran p $validresponse and got the following:

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.

This intrigues me, as the paragraph is from a printf from several lines before. In this particular script, it is the only printf that has run so far, but why the output was saved to the next created variable is beyond me. Any suggestions?

EDIT: After looking at choroba's suggestion, the same problem occurs with any type of redirection, whether piping, using tee, or stderr/stdout redirection. As such, I'm thinking it may be a problem with bash? That is, the only way I can run it is without any kind of logging (at least to my knowledge, which is admittedly quite limited).

Upvotes: 1

Views: 699

Answers (2)

Kenneth Hoste
Kenneth Hoste

Reputation: 2971

You want to enable autoflushing, so that the Perl print buffer is flushed automatically after something is printed. This is the default behavior when a Perl script outputs to a terminal window, but when the output is redirected in any way, the default is to buffer the output. Enabling autoflushing disables the buffering.

You can enable autoflushing by adding the following two lines to the top of the Perl script (below the Perl hashbang line, of course):

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

Upvotes: 1

Ilion
Ilion

Reputation: 6872

When you redirect with pipes or similar you are (normally) redirecting STDOUT. All of the print statements go to STDOUT, so when redirecting the will be sent to whatever process you are piping to. Without seeing the full command you are using I can't say exactly why you aren't seeing the STDOUT messages, but they are obviously being swallowed by the redirection. Whether or not that is actually a problem if for you to decide.

the line

$response = <STDIN> ;

causes the script to wait for input from STDIN which is why you see the prompt. You are not piping anything in to STDIN so it waits.

Upvotes: 0

Related Questions