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

How do I write information to a file that is currently opened? Please see below for a clearer explanation on what I mean. I have this script below that basically write some information to a log file.
#!/usr/bin/perl use warnings; use strict; $|++; my $main_log = '/tmp/main_log.txt'; my $sub_log = '/tmp/sub_log.txt'; print "Start: Coming from the script.\n"; open( my $main_log_file, '>>', $main_log ) or die( "Error: Cannot open $main_log" ); print $main_log_file "Coming from re-opening " . "the opened log file.\n\n"; open( my $sub_log_file, '<', $sub_log ) or die( "Error: Cannot open $sub_log" ); print $main_log_file $_ while( <$sub_log_file> ); close( $sub_log_file ); close( $main_log_file ); <>; # This will just pause the script. print "End: Coming from the script.\n";
When I execute it like this (note that the name of the log file is the same as log file in the script),
#$ perl test.pl > /tmp/main_log.txt
Since I added the '<>;' statement, it will pause the script before it completely ends. Here the log file before the '<>;' statement. So, the additional information is being written to the log file.
Start: Coming from the script. Coming from re-opening the opened log file. Coming from sub-log file.
And here's the output after the '<>;' statement. The 'additional information' becomes
Start: Coming from the script. End: Coming from the script. ened log file. Coming from sub-log file.
So, the output that I want is something like this.
Start: Coming from the script. Coming from re-opening the opened log file. Coming from sub-log file. End: Coming from the script.
So, is there a workaround on what I am trying to do?

Replies are listed 'Best First'.
Re: How to Write Information to an Opened File
by almut (Canon) on Sep 16, 2009 at 02:42 UTC

    The problem is that the shell and your script aren't sharing a common filepointer. So the shell simply continues to write its second line (which it gets from your script) immediately after the first one where it left off, independently of what your script has written to the file in the meantime... The shell's filepointer is not being advanced when your script is writing to the file.   IOW, this won't work.

      Your explanation makes sense. Thanks.
Re: How to Write Information to an Opened File
by ww (Archbishop) on Sep 16, 2009 at 02:29 UTC
    Rather than a workaround, you may want to read perlopentut (gentle) and open.

    Update with code: As the docs for open point out, this is NOT the preferred way to do it, but does this perhaps do what you wanted (preserve the prior content of main_log.txt, and append the content of sub_log.txt)?

    # 795500 # $| = 1; # autoflush my $main_log = 'main_log.txt'; my $sub_log = 'sub_log.txt'; open LOGFILE, '<', $main_log or die "Cannot open $main_log for read, $!"; my $prior_content; while (<LOGFILE>) { $prior_content = $prior_content . $_; } close( LOGFILE ); open LOGFILE, '>', $main_log or die "Cannot open $main_log for write, $!"; print LOGFILE $prior_content; print LOGFILE "\n---\n"; print LOGFILE "\n\tStart: Coming from the script.\n"; open( SUBLOG, '<', $sub_log ) or die( "Error: Cannot open sub_log" ); print LOGFILE $_ while( <SUBLOG> ); close( SUBLOG ); print LOGFILE "\n\tEnd of sub_log as read by script.\n"; print LOGFILE "\tEnd: Coming from the script.\n"; close( LOGFILE );

    If it's not what you intended, you may wish to deal with the problems almut pointed out... AND clarify your question (because your code doesn't do so for me).

      Interesting solution. I will give a thought to your code. Thanks.
Re: How to Write Information to an Opened File
by bichonfrise74 (Vicar) on Sep 16, 2009 at 15:55 UTC
    So, basically I want to insert a sub-log to a main log that is currently open. I was thinking of what people mentioned here and realized that I should not even be attempting to 'open' the main log file that is currently open. Instead I should just open the sub-log and print it on the standard output which will then be placed in the main log.

    Anyway, to people who might encounter this twisted logic. Here's the code that would do this.
    #!/usr/bin/perl use warnings; use strict; my $main_log = '/tmp/main_log.txt'; my $sub_log = '/tmp/sub_log.txt'; print "Start: Coming from the script.\n"; print "Coming from re-opening the opened log file.\n\n"; open( my $sub_log_file, '<', $sub_log ) or die( "Error: Cannot open $sub_log" ); print $_ while( <$sub_log_file> ); close( $sub_log_file ); print "End: Coming from the script.\n";
    To run, simply do this.
    #$ perl test.pl > /tmp/main_log.txt
    And I think this would be a good example of I know what I mean. Why don't you?