in reply to return from external subroutine

At a guess:
  1. you're running on windows
  2. the first script is keeping the file open when you launch the second. (i.e. you've forgotten the close call in parse_file)
Ordinarily, you can't delete or rename an open file under windows.

If you can't see an obvious missed close, you can use filemon to see what files are open and you might also want to check the value of $! when the open fails.

It might be something else since I've not read the unformatted code you've posted.

Replies are listed 'Best First'.
Re^2: return from external subroutine
by kathys39 (Acolyte) on Aug 23, 2007 at 17:08 UTC
    I'm running on Ubuntu 6.10. Below are my complete (except for Parse.pm which is over 300 lines long...

    Main file -
    #! /usr/bin/perl use Parse; use Moving; use File::Copy my @filelist = (); # all filenames will go into this global array my $txt_folder = '/temp/'; &check_folders($txt_folder); foreach $file (@filelist) { print "file is $file\n"; Parse::parse_file($file); Moving::move_file($file); } sub check_folders { #iterate thru directory, this works my($dir) = @_; local (*FOLDER); # use local for filehandles my(@subfiles, $file, $specfile); opendir(FOLDER, $dir) or die "cannot open $dir"; @subfiles = readdir(FOLDER); closedir(FOLDER); foreach $file (@subfiles) { # ignore files beginning with a period next if ($file =~ m/^\./); #$specfile = $dir . ':' . $file; $specfile = $dir . $file; if (-d $specfile) { print "directory is $specfile\n"; &check_folders($specfile); # RECURSION } elsif (-f $specfile) { push(@filelist, $specfile); # # do your text line stuff here }#if }#for }#sub __END__

    Moving.pm
    package Moving; use File::Copy; sub move_file { $oldfile = $_[0]; $newlocation="/data/bst/processed/"; move($oldfile, $newlocation) or die ("Couldn't move file"); return $oldfile } return 1;

    Now relevant parts of Parse.pm
    package Parse; use File::Copy; use Cwd; use Switch; sub parse_file { use DBI; use DBD::mysql; $dsn = "DBI:mysql:test:localhost"; $dbh = DBI->connect($dsn,"root","",{RaiseError=>1}); $newlocation = "/data/processed/"; $file = $_[0]; print "file is $file\n"; open(INFILE, $file) or die ("Unable to open $file"); while ($line = <INFILE> ) { # parse the file, put stuff in db } #end while print "done parsing\n"; $dbh->disconnect(); close(INFILE); } # end function return 1;
      Since you said the Moving::move_file was never called, so chances are that you have an infinite loop in Parse::parse_file. Try to insert a few print statements to see where it hangs.

      Speaking for infinite loops: Once you've got a symbolic link from one directory to a subdirectory you script will loop.

      You could circumvent this by checking for symlinks with -l.

      And use strict and warnings - really!

        Bingo - that was it - I had put an exit statement in my while loop a long time ago, and it was exiting the Parse.pm script prematurely. Thanks for all the help -
      Do you get to the "done parsing" print statement from Parsing.pm? Can you save the return value of parse_file() and print it out so that you can see what it is before starting the move attempt?

      And, definitely, use strict and use warnings.