为什么Perl在退出之前不打印最后一个文本?

时间:2009-03-11 19:53:14

标签: perl printf exit

我的代码不会在“exit;”之前运行最后一行,我不知道为什么。我试图在printf $fh之前添加一条exit行,但这也不起作用;它不会打印任何一行。除了退出前的最后一个打印语句外,其他所有内容都打印正常。

有什么理由发生这种情况?或者更好的是,如何修复或解决它?

    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;
    }

编辑:
我复制的部分代码包含了这个

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

也许这就是为什么我的结果不能重复......

6 个答案:

答案 0 :(得分:10)

我给了R. Bemrose我的投票,但如果$ fh是 FILE HANDLE ,您可能还希望在终止之前close

此外,您错误地使用了printf。 printf '打印文件'。它的'打印格式'。

对于最后一个例子

  print $fh 'Message' ;  

你需要的只是。

printf旨在用于:

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

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

及其等同于做

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

正因为如此,如果您的任何连接变量扩展到其中包含'%',您就会冒不必要的代码风险。有关陷入此陷阱的人员的示例,请参阅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

进一步探索

我一直在探究你的问题,因为我无法让你的“缓冲”状态发生。无论我是否冲洗它们,我的所有文件都会被正确刷新。 (Perl 5.10)。

这是我正在尝试的代码片段:

#!/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";
    }
}

我正在使用你对printf的错误使用。 被注释的行会弹出一条错误消息,因为它没有提供'n'参数而无效,并且它会因:

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

在执行'last line'打印之前(也很糟糕,但是没有%符号,所以它很好)使输出文件中不存在“最后一行”。

请修改你的printf并使用普通旧版,看看是否能解决你的问题。

答案 1 :(得分:9)

Perl缓冲其输出。您可以使用

关闭自动缓冲
local $| = 1;
编辑:我不知何故命中了!而不是|第一次......固定。不知道是怎么回事,他们在键盘的两侧。

答案 2 :(得分:8)

尝试“中止。\ n”

这看起来像是一个缓冲问题。

答案 3 :(得分:3)

关于正确使用print的问题,你会对自己造成一些困难。

插入变量而不是将字符串连接在一起。 使用一个带有要打印的字符串列表的print语句,而不是多个字符串。

这是一种方式:

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

    exit;
}

三元运算符假端的()是一个空列表,当连接的参数被展平时,它将消失。如果我使用了空字符串(''),则每个不匹配的标准都会在结果中产生额外的空白行。

您还可以在每个项目上添加自己的换行符,然后跳过联接,如果您觉得这更具可读性:

    print $fh  
        "Partial match found.\n",
        $matched_uid   ? "UID #: $arguid exists.\n" : '',
        ...

答案 4 :(得分:2)

您需要在最后一个printf中添加一个尾随\ n。否则输出不会刷新到控制台。

答案 5 :(得分:0)

David Norman是对的,还是问题出在其他地方。我只是将if块中的代码输入perl解释器,然后打印出“Aborting”。正如所料。 (即使没有终止换行符,它也适用于我。)