得到错误“无法打开输入文件没有这样的文件或目录”,我无法弄清楚原因

时间:2013-08-16 16:31:40

标签: perl

我有一个会读取日志的脚本。日志的前三个字符是该客户的代码(即xxx)。程序启动并运行然后因此错误而停止。 out.txt位于日志目录中,适用于所有客户,直至某个客户。这个权限与所有其他权限相同。程序停止,没有任何超过该客户的文件。

    $adminDir = "/data1/Scripts";
    $scriptDir =  "/data1/Scripts";
    chomp($toDay = `date +%m-%d-%y`);
    @prodDirs = ();
    open(DIRS, "$scriptDir/production_dirs") or warn "Can't open $scriptDir/production_dirs file: $!\n";
    $count = 0;
    while (<DIRS>) {
             if(index($_, '#') < 0) {
                    chomp($prodDirs[$count++] = $_);
             }
    }
    close(DIRS);

    foreach $jobDir (@prodDirs) {
            @dirFields = split(/\|/, $jobDir);
            $srcDir = $dirFields[0];
            $workDir = "$srcDir";
            $logFile = $workDir . "/log/" . $dirFields[11] . "log";
            $oldLog = $logFile;
            $oldLogBack = $oldLog . "." . $toDay;
            $newLog = $workDir . "/log/" . "out.txt";

            open(FILE, "<$logFile")|| die "Can't open input file $!";
            open(OUT, ">$newLog") || die "Can't open output file $!";
            while(<FILE>) {
                    print OUT if($_=~/(.*)(Jan  1)(.*?)/gs);
            }
     }

2 个答案:

答案 0 :(得分:4)

一些快速说明。

为什么使用strictwarnings

使用它可以帮助您更快地捕获印刷错误,然后继续发现更重要的问题。

读:

为什么 三个而不是两个arg 形式的open()

请记住,two-arg形式的开放已被破坏。例如,让我们来一个名为' foo'的文件。现在这个文件在开头有一个领先的空格。所以你要打开它..

open FILE, ' foo'   || die $!;
open FILE, '< foo'  || die $!;
open FILE, '<  foo' || die $!;

这里看错了什么?这些都不会起作用。另请注意,如果您不小心使用带有特殊字符的文件名,您的代码可能不会像预期的那样运行。

这种方法更清洁,使用更安全。请参阅perldoc open

open my $fh, '<', 'foo' or die "failed $!";

要记住的事情

  • 使用three-arg形式的打开
  • 使用lexical scalars存储文件句柄引用
  • 使用or代替||来检查打开
  • 是否成功,从而避免出现问题

答案 1 :(得分:2)

我参加了您的计划并添加到use strict;use warnings;

use strict;
use warnings;

my $adminDir = "/data1/Scripts";
my $scriptDir =  "/data1/Scripts";

chomp( my $toDay = `date +%m-%d-%y` );
my @prodDir;
open(DIRS, "$scriptDir/production_dirs") or die "Can't open $scriptDir/production_dirs file: $!\n";

my $count = 0;
while ( <DIRS> ) {
    if ( index($_, '#') < 0 ) {
        chomp ( $prodDirs[$count++] = $_ );
    }
}
close(DIRS);

for my $jobDir (@prodDirs) {
    my @dirFields = split(/\|/, $jobDir);
    my $srcDir = $dirFields[0];
    my $workDir = "$srcDir";
    my $logFile = $workDir . "/log/" . $dirFields[11] . "log";
    my $oldLog = $logFile;
    my $oldLogBack = $oldLog . "." . $toDay;
    my $newLog = $workDir . "/log/" . "out.txt";

    open(FILE, "<" , $logFile)|| die "Can't open input file $!";
    open(OUT, ">", $newLog) || die "Can't open output file $!";
    while(<FILE>) {
        print OUT if($_=~/(.*)(Jan  1)(.*?)/gs);
    }
}

我得到的错误:

Global symbol "@prodDirs" requires explicit package name at ./test.pl line 16.
Global symbol "@prodDirs" requires explicit package name at ./test.pl line 21.

在第10行中,您初始化了@prodDir,但是在您的循环中,您使用了@prodDirs(最后使用s

这就是为什么每个人都在对你说“使用use strict;use warnings; ”。这两个编译指示可以捕获90%的编程错误。