Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

My script runs file when run from a command-line but hangs on the open() call when invoked from Java. No Error is printed out and the print on the following line is never called. Any thoughts on why this would stall on opening the syslog file?

no warnings "all"; use strict; use Net::Dev::Tools::Syslog; my $syslog_file = "tail -n 0 -f /var/log/messages |"; # create syslog parsing object ( $syslog_obj, $error ) = Net::Dev::Tools::Syslog->parse( -report => 1, -parseTag => 1, #-dump => './dump2', -debug => 0, -moreTime => 1, -format => 'noHost', ); unless ($syslog_obj) { printf( "sylog object constructor failed: %s\n", $error ); exit(1); } print STDOUT "Reaches here: $syslog_file \n"; open(FH, "$syslog_file" ) || die "ERROR: open failed: $!\n"; print STDOUT "Doesn't reach here\n"; while (<FH>) { #do whatever } close(FH); sleep 1;

The Java call looks something like this:

Runtime rt = Runtime.getRuntime(); Process proc = null; proc = rt.exec("perl myscript.pl");

Replies are listed 'Best First'.
Re: Perl won't Open() when called from Java
by Marshall (Canon) on Feb 23, 2012 at 19:02 UTC
    Well first of all: 'no warnings "all";' this is not a good idea. I would "use warnings;". Might learn something useful from these warnings! Of course, print the variable $syslog_file before you use it - probably some big clue there as to why the open() doesn't work!

    Update: Oh, I see that you do print $syslog_file. Look for leading/trailing white space characters in this. A newline or something like that might be causing the trouble.

    Another update: Add $|=1; to the code. This turns off buffering to STDOUT. You may be actually reaching past the open(), but just can't see the message that this happened. Or alternatively, print to STDERR which is by default un-buffered.

      I was able to fix this but can't understand why. I replaced:

      my $syslog_file = "tail -n 0 -f /var/log/messages | "; print STDOUT "some debug line: $syslog_file\n"; open(FH,"syslog_file") print STDOUT "didn't reach before\n";

      with:

      my $syslog_file = "tail -n 0 -f /var/log/messages | "; print STDERR "some debug line: $syslog_file\n"; open(FH,"syslog_file") print STDERR "reaches now\n";

      Why would changing to STDERR make a difference?

        Oh I see. STDERR is unbuffered, but STDOUT buffers. Thanks!
      Considering that $syslog_file is assigned a string literal, without any interpolation, I don't think the OP should expect any surprises here.

      And neither should we.

        my $syslog_file = "tail -n 0 -f /var/log/messages |"; doesn't look like a string_literal to me. yes this is...was thinking incorrectly. When I looked at the code, by the time I got to the open(), I was thinking that the op had done a system call to get the output of tail. My goof. But it appears that my $|=1; suggestion did work.
Re: Perl won't Open() when called from Java
by JavaFan (Canon) on Feb 23, 2012 at 19:42 UTC
    How do you determine it hangs in the open? What happens if you add a die statement right after your open?

    I don't know what you are doing inside your while loop, but if you aren't printing enough so your buffer gets flushed, you won't see anything. And normally speaking, your while loop will never terminate; if you actually don't print to STDOUT from there, you will never see the output of your print statement.

    Perhaps you should turn off buffering.

      Buffering was actually the problem. I assumed it was hanging but really it just wasn't showing any output for the print. Thanks. For others, this was solved by adding $|=1; to my code to disable buffering