-2

I have a script that will read a log. The first three characters of the log are a code for that customer (i.e. xxx). The program starts and runs then stops with this error. The out.txt is located in the log directory for all customers up to a certain one. This one has the same permissions as all the others. The program stops, and nothing past that customer gets the file.

    $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);
            }
     }
Prix
  • 19,173
  • 14
  • 69
  • 128
user2690096
  • 13
  • 1
  • 3

2 Answers2

4

A few quick notes.

Why use strict and warnings?

Using this will help you catch typographical errors more quickly and then move on to being able to find more significant problems.

Read:

Why three-arg and not two-arg form of open() ?

Keep in mind that the two-arg form of open is broken. For example let's take a file called ' foo'. Now this file has a leading whitespace at the beginning. So however you go to open it..

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

See anything wrong here? None of these will work. Note also that If you accidentally use a filename with special characters, your code likely will not behave as you would as expect.

This approach is much cleaner and safe to use. Refer to perldoc open

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

Things to remember

  • Use the three-arg form of open
  • Use lexical scalars to store filehandle references
  • Avoid problems by using or instead of || to check the success of open
Community
  • 1
  • 1
hwnd
  • 67,942
  • 4
  • 86
  • 123
2

I took your program and added in use strict; and 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);
    }
}

The error I get:

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

In line # 10, you initialized @prodDir, but then in your loop, you used @prodDirs (with an s on the end.

This is why everyone is saying to you "Use use strict; and use warnings;". These two pragmas catch 90% of your programming errors.

David W.
  • 102,141
  • 38
  • 210
  • 325