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

I'm writing a small script that processes a proxy log file. I take the results of my script and write it to a file. I then close the file using close(OUTPUT); where OUTPUT is my file handle. I next try to email the file using a dos program called BLAT. To do this, I call  system ("c:\\blat\\blat $filename -t \"myemail@mydomain.com\""); This command, though, reports that the file was not found. I thought the close() call flushes the buffer and creates the file, but for some reason, the file doesn't seem to exist until my script completes running all together. Can anyone offer any ideas/suggestions?

Replies are listed 'Best First'.
Re: Waiting for file creation
by tcf22 (Priest) on Jun 03, 2003 at 18:55 UTC
    I've used blat, and I would recommend using a module such as Mail::Sender instead. We were using blat through a CGI and blat wouldn't always terminate correctly, and blats would eventually build up and slow/crash the server.

    Mail::Sender doesn't make you create a temporary file, which is more convenient(at least for me).

    If you are forced to use blat, does $filename contain the full windows path(ie. c:\temp\msg.txt). If not, I think that could be the reason that it isn't finding it, because blat may not be looking in the same directories as perl does.
      I am not running the script via CGI and Blat works well for my needs (though thanks for the suggestion). $filename does not contain the full path, but I've testing running the code with $filename set to a file that exists prior to running the script and it works fine (Blat looks in the directory from which the script was run).
Re: Waiting for file creation
by vek (Prior) on Jun 03, 2003 at 18:55 UTC
    We're really going to have to see some code before we can help you out here.

    -- vek --
Re: Waiting for file creation
by Anonymous Monk on Jun 03, 2003 at 19:03 UTC
    Here's most of the code for the problem I'm talking about:
    @logs = <@ARGV>; %reports=(); %results=(); open (INPUT_IN, "FindSitesInput.txt")|| die "Can't open input file! :$ +!"; while (defined($currentLine = <INPUT_IN>)) { $_=$currentLine; if(! m/^\#/) { #split currentLine into tab-delimited tokens @tokens = split("\t",$currentLine); my @temp = ($tokens[1], $tokens[2], $tokens[3], $tokens[4]); $reports{$tokens[0]}=\@temp; my @data=(); $results{$tokens[0]}=\@data; } } } close (INPUT_IN) || die "Can't close input file: $!"; #now run the reports on each log file foreach $logfile(@logs) { open (LOG_IN, "$logfile")|| die "Can't open $logfile! :$!"; while (defined($currentLine = <LOG_IN>)) { @tokens = split(" ",$currentLine); foreach $rep (keys %reports) { @comparisons = split(" ", $reports{$rep}[0]); foreach $item (@comparisons) { if($reports{$rep}[2] == "site") { $_=$tokens[6]; if(/$item/) { push @{$results{$rep}}, $currentLine; } } elsif ($reports{$rep}[2] == "ip") { $_=$tokens[2]; if(/$item/) { push @{$results{$rep}}, $currentLine; } } } } } close (LOG_IN) || die "Can't close log file: $!"; #now write the output files for each report for this log foreach $rep (keys %results) { open (OUTPUT, ">$logfile-$rep")|| die "Can't open $logfile-$re +p! :$!"; print OUTPUT @{$results{$rep}}; if(close OUTPUT) { if(!($reports{$rep}[2]eq"none")) { system("c:\\blat\\blat $logfile-$rep -t \"$reports{$re +p}[2]\""); } } else { die "Can't close output file: $!"; } } }
    The input values are read from a file (I've tested to verify that the data structure is created properly).

      Not really help to your problem, just a few comments:

      1. You do not have
        use strict; use warnings;
      2. The code
        @logs = <@ARGV>;
        is supposed to glob the parameters (expand *.txt to the list of files that match that wildcard) right? You might like G better.

      3. @tokens = split("\t",$currentLine); my @temp = ($tokens[1], $tokens[2], $tokens[3], $tokens[4]); $reports{$tokens[0]}=\@temp; my @data=(); $results{$tokens[0]}=\@data;
        would be better writen like this:
        my ($rep, @tokens) = split("\t",$currentLine); $reports{$rep}=\@tokens; $results{$rep}=[];
      4. foreach $logfile(@logs) should be foreach my $logfile(@logs). The same for other loops.

      Jenda
      Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live.
         -- Rick Osborne

      Edit by castaway: Closed small tag in signature