perl错误:在连接(。)或字符串中使用未初始化的值$ _

时间:2015-03-25 12:24:39

标签: perl

我收到以下错误:

Use of uninitialized value $_ in concatenation (.) or string at checkfornewfiles.pl line 34.

尝试运行以下代码时:

#!/usr/bin/perl -w
#Author: mimo
#Date 3/2015
#Purpose: monitor directory for new files...

AscertainStatus();
        ######### start of subroutine ########
sub AscertainStatus {
    my $DIR= "test2";

    ####### open handler #############
    opendir (HAN1, "$DIR") || die "Problem: $!";

    ########## assign theoutput of HAN1 to array1 ##########
    my @array1= readdir(HAN1);

    ######## adding some logic #########

    if ("$#array1" > 1) {   #### if files exists (more than 1) in the directory #######
            for (my $i=0; $i<2; $i++) {shift @array1;}      ####### for i in position 0 (which is the . position) loop twice and add one (the position ..) get rid of them #######
            MailNewFiles(@array1);
    }       else { print "No New Files\n";}

}

sub MailNewFiles {
    $mail= "sendmail";

    open ($mail, "| /usr/lib/sendmail -oi -t" ) ||die "errors with sendmail $!"; # open handler and pipe it to sendmail
    print $mail <<"EOF";    #print till the end of fiEOF
    From: "user";
    To: "root";
    Subject: "New Files Found";

    foreach (@_) {print $mail "new file found:\n $_\n";}
EOF
    close($mail);
}

#End

我是perl的新手,我不知道出了什么问题。任何人都可以帮助我吗?

3 个答案:

答案 0 :(得分:5)

一些建议:

  • Perl不是C.你的主程序循环不应该是一个声明的子程序,然后你执行它。消除AscertainStatus子例程。
  • 始终,始终use strict;use warnings;
  • 正确缩进。它使人们更容易阅读您的代码并帮助分析您做错了什么。
  • 使用更现代的Perl编码风格。 Perl是一种古老的语言,多年来,我们开发了新的编码风格和技术,以帮助您消除基本错误并帮助其他人阅读您的代码。
  • 当有Perl模块可以以更标准的方式为您执行此操作时,不要使用系统命令,并且可能会执行更好的错误检查。 Perl附带了Net::SMTP来处理邮件通信。使用它。

错误Use of uninitialized value $_ in concatenation (.) or string正如它所说的那样。您正在尝试使用尚未设置的变量的值。在这种情况下,变量是@_语句中的foreach变量。您的foreach不是真foreach,而是print语句的一部分,因为您的EOF 之后 你的for陈述。这看起来像是一个错误。

此外,@_的价值是多少?此变量包含已传递给子例程的值列表。如果没有传递,则将是未定义的。即使@_未定义,foreach (undef)也会跳过循环。但是,由于foreach (@_) {是要打印的字符串,因此Perl程序将在未定义@_的情况下崩溃。

如果您从-w移除#!/usr/bin/perl,您的程序实际上会“工作”(注意引号),您会看到{{1}将字面打印。

我不建议您不要使用foreach所做的警告。实际上,我建议你-w而不是use warnings;。但是,在这种情况下,它可能会帮助您查看错误。

答案 1 :(得分:0)

EOF行后面有foreach。它包含$_,在此处进行插值,但$_尚未初始化,因为它不在foreach循环中。它不是代码而只是文本。在foreach之前移动EOF。

但可能你想要

sub MailNewFiles {
    $mail= "sendmail";

    open ($mail, "| /usr/lib/sendmail -oi -t" ) ||die "errors with sendmail $!"; # open handler and pipe it to sendmail
    local $"="\n"; # " make syntax highlight happy
    print $mail <<"EOF";    #print till the end of fiEOF
From: "user";
To: "root";
Subject: "New Files Found";

New files found:
@_
EOF
    close($mail);
}

有关$"的更多信息,请参阅perlvar

答案 2 :(得分:0)

消息

Use of uninitialized value $xxx in ...

非常简单。遇到它时,这意味着您以任何方式使用变量($ xxx),但该变量尚未初始化。

有时,在代码开头添加初始化命令就足够了:

my $str = '';
my $num = 0;

有时,您的算法错误,或者您只是错误输入了变量,例如:

my $foo = 'foo';
my $bar = $ffo . 'bar'; # << There is a warning on this line
                        # << because you made a mistake on $foo ($ffo)