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

mim*_*imo -3 perl

我收到以下错误:

Use of uninitialized value $_ in concatenation (.) or string at checkfornewfiles.pl line 34.
Run Code Online (Sandbox Code Playgroud)

尝试运行以下代码时:

#!/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
Run Code Online (Sandbox Code Playgroud)

我是perl的新手,我不知道出了什么问题.谁能帮我 ?

Dav*_* W. 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陈述的一部分.这看起来像是一个错误.EOFfor

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

如果您在删除-w#!/usr/bin/perl,你的程序实际上将" 工作 "(注意引号),你会看到你foreach确实将会打印.

我不建议你不要使用警告-w.事实上,我推荐你use warnings;而不是-w.但是,在这种情况下,它可能会帮助您查看错误.