Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why doesn't Perl print the last text before it exits?

Tags:

printf

exit

perl

My code won't run the last line right before " exit; " and I have no clue why. I tried to put an additional printf $fh line before exit, but that didn't work either; it would not print either line. Everything else prints fine except the last print statements before the exit.

Any clue why this happens? Or better yet, how to fix or work around it?

    if($i>0 && $i<3)
    {
        printf $fh "Partial match found.\n";
        if($matched_uid){printf $fh "UID #: ".$arguid." exists.\n";}
        if($matched_id){printf $fh "ID #: ".$argid." exists.\n";}
        if($matched_uname){printf $fh "Username: ".$arguname." exists.\n";}
        printf $fh "Aborting."; 
        exit;
    }

EDIT:
Part of the code I copied contained this

select $fh; $| = 1; #set auto flush

Maybe this is why my results couldn't be duplicated....

like image 717
CheeseConQueso Avatar asked Nov 27 '22 06:11

CheeseConQueso


1 Answers

I gave R. Bemrose my vote, but if $fh is a FILE HANDLE you may want to also close it prior to terminating.

Also, you are using printf wrongly. printf is not 'print file'. its 'print format'.

For that last example

  print $fh 'Message' ;  

Is all you need.

printf is intended to be used thus:

printf $fh 'some format %s  and more %s ' ,  $var , $var ; 

or

   printf 'some format %s  and more %s ' ,  $var , $var ; 

and its equivelant to doing

   print $fh sprintf 'format %s more %s' , $var , $var ; 

And because of this, you're putting needless code risks in in the event any of your concatenated variables expand to have '%' in them. For an example of people falling into this trap, see Q:308417:Why does my Perl script remove characters from the file?

perldoc -f print

print FILEHANDLE LIST
print LIST
print   Prints a string or a list of strings.

perldoc -f printf

printf FILEHANDLE FORMAT, LIST
printf FORMAT, LIST
      Equivalent to "print FILEHANDLE sprintf(FORMAT, LIST)", except that "$\" 
      (the output record separator) is not appended

Further Probing

I've been probing into your problem further because I can't get your "buffering" condition to occur. All my files are properly flushed whether or not I flush them. ( Perl 5.10 ).

Heres my code snippet I'm trying:

#!/usr/bin/perl 

use strict;
use warnings;


open my $fh , '>' , '/tmp/oo.txt'; 

my $exit_at = int(rand( 200_000 ));
print "$exit_at\n";
sleep 2;
for ( 0 .. ( $exit_at * 2 ) ){ 
    print $fh $_;
    if ( $_ == $exit_at ){
        printf $fh '%n' ; # Bad Code Causes Early Death. 
        printf $fh 'last line';
        exit; 
    }
    if ( $_ % 1000  ){
        print $fh "\n";
    }
}

I'm using your miss-use of printf. The line that is commented ejects an error message, because its not valid due to nobody providing the 'n' parameter, and it dies with:

Modification of a read-only value attempted at iotest.pl line 15.

Before executing 'last line' print ( also bad, but theres no % symbols in it so its fine ) making 'last line' absent from the output file.

Please fix up your printf and use plain-old-print instead and see if that solves your problem.

like image 54
Kent Fredric Avatar answered Dec 06 '22 19:12

Kent Fredric