-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,417
  • 15
  • 73
  • 132
user2690096
  • 13
  • 1
  • 3
  • 9
    `use strict; use warnings;` – Quentin Aug 16 '13 at 16:35
  • 7
    Use : `open(my $FILE, '<', $logFile)|| die "Can't open input file '$logfile' : $!";` – Toto Aug 16 '13 at 16:39
  • 2
    Why do you only `warn` if you cannot open the directory instead of `die`ing. Do you really want the rest of your program to run if you can't open the directory? – DJG Aug 16 '13 at 16:48
  • I used the "Can't open input file $logFile" and found out what was really wrong. I'm sorry to have bothered the group with this question. Thanks for the suggestions and help! – user2690096 Aug 16 '13 at 17:23
  • Voting to close. OP already solved his problem. – pilcrow Aug 16 '13 at 19:06
  • If you understand your errors and reviewed given answers, please accept and close this question. – hwnd Aug 17 '13 at 13:34

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
  • 69,796
  • 4
  • 95
  • 132
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.
  • 105,218
  • 39
  • 216
  • 337