HELP! File Copy, Move and Rename will not work in my script!

Discussion in 'Perl Misc' started by kwalike57, Jan 8, 2008.

  1. kwalike57

    kwalike57 Guest

    Hello.

    I have a perplexing question that seems like it should be very
    simple. I have a perl script that in a nutshell, reads a directory
    and then looks for a specific file naming convention which is matched
    up by using a regExp that loads a variable $FILE. Once it finds this
    it Connect:Directs (copies file) the file to a remote node. After
    this is done I send an email notification that the file transfer
    completes. My problem is that when this whole process completes, I
    want to rename the $FILE to a file.done format. I do this with the
    rename function normally but saying rename ($FILE, $FILEDONE). This
    is not working. I can tell the script to print out the value of $FILE
    and $FILEDONE and both values are correctly indicated. For example if
    $FILE is FILEa.txt then $FILEDONE would be FILEa.txt.done.

    So my question is, why won't my file rename properly. My script exits
    with an error indicating cannot rename $FILE.

    In light of this I decided to try to copy $FILE and then also tried to
    move $FILE. Neither work. This script runs on a Windows box and so I
    tried to manually execute the copy and move commands from the command
    line and both work fine. I can rename, copy and move the file with no
    problem. I am using File::Copy in my script. I have tried using the
    system command to execute the copy and moves and I have tried to
    manually type in the copy and moves as well in the script. I have
    only tried to do this with the variable values and have not tried
    executing these commands with a qualified path to the file name.

    Any ideas? This seems like it should be the easiest part of the whole
    process and it has taken up a bunch of time trying to get this last
    element to work.

    Thanks for your help!!

    Karin Walike
    kwalike57, Jan 8, 2008
    #1
    1. Advertising

  2. kwalike57 wrote:
    > Hello.


    Your second posting of the same problem and you still have not posted
    any code.

    My crystal ball seems to think that you may have a problem with
    directories, either incorrect names or missing completely? Possibly on
    line 42?


    John
    --
    Perl isn't a toolbox, but a small machine shop where you
    can special-order certain sorts of tools at low cost and
    in short order. -- Larry Wall
    John W. Krahn, Jan 8, 2008
    #2
    1. Advertising

  3. kwalike57

    J. Gleixner Guest

    kwalike57 wrote:
    > Hello.
    >
    > I have a perplexing question that seems like it should be very
    > simple. I have a perl script that in a nutshell, reads a directory


    Care to post a short example? How the heck do you expect
    anyone to be able to help, if we can't see what you're doing?

    [...]
    > So my question is, why won't my file rename properly. My script exits
    > with an error indicating cannot rename $FILE.

    [...]

    Fix your error to include why it failed and the values of the filenames
    it's trying to copy/move, maybe that'll help you figure out the problem.
    It's likely either you're not in the directory you think you're in or
    it's a permission problem.

    perldoc File::Copy

    All functions return 1 on success, 0 on failure. $! will be set if an
    error was encountered.
    J. Gleixner, Jan 8, 2008
    #3
  4. kwalike57

    kwalike57 Guest

    Re: HELP! File Copy, Move and Rename will not work in my script!

    On Jan 8, 3:33 pm, "John W. Krahn" <> wrote:
    > kwalike57 wrote:
    > > Hello.

    >
    > Your second posting of the same problem and you still have not posted
    > any code.
    >
    > My crystal ball seems to think that you may have a problem with
    > directories, either incorrect names or missing completely?  Possibly on
    > line 42?
    >
    > John
    > --
    > Perl isn't a toolbox, but a small machine shop where you
    > can special-order certain sorts of tools at low cost and
    > in short order.                            -- Larry Wall


    Here is the code...

    #!/perl/bin/perl
    #
    #NewAutoConDir.pl
    #Karin Walike
    #12.01.07
    #
    #Connect:Direct process automation for server PKSW1714
    #The script sleeps and wakes up to check and see if there is a file
    #has been loaded to the server for Connect:Direct to customer.
    #
    #
    #We currently have XX customers sending/receiving data to this node.
    #
    #Product list: xx, xx, xx, xx, xx,

    use MIME::Lite;
    use Cwd;
    use File::Copy;

    my $date=localtime();

    my $dirVM="D:\\Prod_D\\BOP\\Data\\SMSDATA\\PCSWHSLE\\CD\\VM\\";
    my $doneDir="D:\\Prod_D\\BOP\\Data\\SMSDATA\\PCSWHSLE\\CD\\VM\\DONE\
    \";

    my $FILE;
    my @FILES;

    my $doneExt = ".done";

    my $ConDir1="D:\\tools\\'Sterling Commerce'\\'CONNECT Direct v4.1'\
    \'Common Utilities'";
    my $ConDir2="D:\\Prod_D\\BOP\\Scripts\\temp";
    my $ConDir3="D:\\Prod_D\\BOP\\scripts\\triggerDir";

    my $LOG="D:\\Prod_D\\BOP\\Logs\\ConDirLogVM_1.txt";
    my $LOG2="D:\\Prod_D\\BOP\\Logs\\ConDirLogVM_2.txt";

    my $LOG3="D:\\Prod_D\\BOP\\Logs\\ConDirLogVM_3.txt";
    my $LOG4="D:\\Prod_D\\BOP\\Logs\\ConDirLogVM_4.txt";

    my $EXCONDIR="D:\\Prod_D\\BOP\\Scripts\\temp\\ConDirVM.cmd";


    open (OUT,">>$LOG");

    while(1) {


    # Open the directory VM

    if( -d $dirVM ) {
    opendir( VMDIR, $dirVM ) || die "Cannot open directory $dirVM $!";
    }else{
    print "Directory $dirVM does not exist. Exiting...\n";
    exit;
    }

    # Iterate through the directory VM

    opendir(VMDIR, $dirVM) || die "Cannot open directory $dirVM $!";
    #open(VMDIR,"D:\\Prod_D\\BOP\\Data\\SMSDATA\\PCSWHSLE\\VM") || die
    "Cannot open directory $dirVM $!";
    #open(VMDIR,'dir "D:\Prod_D\BOP\Data\SMSDATA\PCSWHSLE\VM" |') || die;

    @FILES = readdir(VMDIR);

    #closedir(VMDIR);

    chomp (@FILES);
    print "\n@FILES\n";

    foreach $FILE ( @FILES ) {

    if ($FILE !~ /^RU_VIRGIN_MOBILE_[0-9]_[0-9][0-9][0-9][0-9][0-9][0-9]
    [0-9][0-9].*\.gz$/) {
    #print "$FILE is not an EMBARQ product...\n";
    goto sleeplabel;
    }else{

    chomp($FILE);

    print "\nFile is $FILE\n";

    print "\nBeginning Connect:Direct processing for VIRGIN MOBILE
    customer file...\n";

    print OUT "\n$date $FILE\n";

    goto sleeplabel if (!$FILE);


    if (file_transfer_complete($FILE)) {
    print "\nFound file $FILE\n";




    open(IN, "$ConDir3\\send_triggerVM.pl");
    open(OUT, ">$ConDir2\\tmp_sendVM.cdp");
    while (<IN>) {
    if (/ConDirFile/) {
    s/ConDirFile/$dirVM$FILE/;
    }
    print OUT $_;
    }
    close(OUT);
    close(IN);

    print "First Connect:Direct pre-processing step passed...\n";

    "$ConDir2\\tmp_sendVM.cdp > D:\\Prod_D\\BOP\\scripts\\temp\\file";
    sleep 10;

    print "Second Connect:Direct pre-processing step passed...\n";

    system $EXCONDIR || errorexit(2, "\nConnect:Direct process failed");


    print "\nConnect:Direct processing for VIRGIN MOBILE customer file
    completed...\n";

    print OUT "\nConnect:Direct Processed for $date $FILE\n";

    # Send email to notify file has been C:D to mainframe

    my $machine = "PKSW1714";

    my $email = '';

    my $email2 = '';

    my $subject = "Connect:Direct Processing VIRGIN MOBILE: $FILE has
    been sent to VIRGIN MOBILE node VSCPFTP01";

    my $body = " Hello, \n\n $FILE has been moved from $machine to
    VSCPFTP01. \n\n Please contact $email2 with questions. \n\n Thanks, \n
    \n IOP Connect:Direct Team\n\n";

    my $server = "10.214.13.55";

    my $msg = MIME::Lite->new(
    From => '',
    To => '',
    Subject => $subject,
    Type => 'TEXT',
    Data => $body
    );

    #Use SMTP to send
    MIME::Lite->send('smtp', $server, Timeout=>60);
    sleep 30;
    $msg->send;
    open(OUT, ">>$LOG"); #reopen closed LOG

    print "\nEmail notification of Connect:Direct transfer sent...\n";


    #sleeplabel2:
    print"\n\n*******Waiting for VIRGIN MOBILE file processing to
    complete*******\n\n";
    sleep 50;

    # Rename the current process to done

    chomp($FILE);

    print "File is writable\n" if -w $FILE;


    $FILEDONE = $FILE . $doneExt;

    chomp($FILEDONE);

    print "filedone=$FILEDONE\n";

    #rename ("D:\\Prod_D\\BOP\\Data\\SMSDATA\\PCSWHSLE\\CD\\VM\
    \RU_VIRGIN_MOBILE_1_20071130.007.gz", "D:\\Prod_D\\BOP\\Data\\SMSDATA\
    \PCSWHSLE\\CD\\VM\\RU_VIRGIN_MOBILE_1_20071130.007.gz.done");
    rename ($FILE, $FILEDONE);

    #if (renamefiles($FILE)) {
    print "\nFile successfully renamed: $FILEDONE\n" || errorexit(14,
    "Could not rename $FILE");
    #}

    #move ($FILE,$FILEDONE) || errorexit(9, "Unable to move $FILE");

    #copy ($FILE,$FILEDONE) || errorexit(12, "Unable to copy $FILE to
    $FILEDONE");

    sleeplabel:
    print"\n\n*******Waiting for VIRGIN MOBILE Connect:Direct file*******
    \n\n";
    sleep 10;


    #
    # Begin Subroutines
    #



    #
    # Sub file_transfer_complete
    #
    # monitor a file for size changes over a brief period
    #
    # parm1 - file name
    # parm2 - delay in seconds (optional)
    #
    sub file_transfer_complete {

    my $filename = shift;
    my $waitTime = shift || 20;

    my $sizefirst = -s $filename; # initial file size
    sleep $waitTime; # wait a while

    my $sizeDelta = -s $filename; #file size after wait

    if( $sizeDelta == $sizefirst ) {
    print "transfer complete $filename 1: $sizefirst\t2: $sizeDelta" ;
    return 1;
    } else {
    print "transfer incomplete $filename 1: $sizefirst\t2: $sizeDelta" ;
    return 0;
    }
    }



    # Sub errorexit print error message to the log and return an error
    code
    #
    sub errorexit {
    my $returncode = shift;
    my $message = shift;
    open (OUT, ">>$LOG");
    print OUT "\n### ERROR $returncode ### $message";
    exit ($returncode);
    }

    # Sub Rename files to .done extension
    #
    sub renamefiles {

    my $file1 = shift;

    my $done = ".done";

    my $file2 = $file1 . $done;

    rename ($file1, $file2) || die "Cannot rename $file1\n";
    }
    }
    }
    }
    }
    kwalike57, Jan 9, 2008
    #4
  5. Re: HELP! File Copy, Move and Rename will not work in my script!

    kwalike57 wrote:
    > On Jan 8, 3:33 pm, "John W. Krahn" <> wrote:
    >>
    >> Your second posting of the same problem and you still have not posted
    >> any code.
    >>
    >> My crystal ball seems to think that you may have a problem with
    >> directories, either incorrect names or missing completely? Possibly on
    >> line 42?


    It looks like my crystal ball is batting .500, correct problem, wrong
    line number.


    > Here is the code...
    >
    > #!/perl/bin/perl


    You should start off with the two pragmas:

    use warnings;
    use strict;

    > #
    > #NewAutoConDir.pl
    > #Karin Walike
    > #12.01.07
    > #
    > #Connect:Direct process automation for server PKSW1714
    > #The script sleeps and wakes up to check and see if there is a file
    > #has been loaded to the server for Connect:Direct to customer.
    > #
    > #
    > #We currently have XX customers sending/receiving data to this node.
    > #
    > #Product list: xx, xx, xx, xx, xx,
    >
    > use MIME::Lite;
    > use Cwd;
    > use File::Copy;


    You don't appear to be using either Cwd or File::Copy?

    > my $date=localtime();
    >
    > my $dirVM="D:\\Prod_D\\BOP\\Data\\SMSDATA\\PCSWHSLE\\CD\\VM\\";
    > my $doneDir="D:\\Prod_D\\BOP\\Data\\SMSDATA\\PCSWHSLE\\CD\\VM\\DONE\
    > \";
    >
    > my $FILE;
    > my @FILES;


    These should be declared inside the loop instead of here.

    > my $doneExt = ".done";
    >
    > my $ConDir1="D:\\tools\\'Sterling Commerce'\\'CONNECT Direct v4.1'\
    > \'Common Utilities'";
    > my $ConDir2="D:\\Prod_D\\BOP\\Scripts\\temp";
    > my $ConDir3="D:\\Prod_D\\BOP\\scripts\\triggerDir";
    >
    > my $LOG="D:\\Prod_D\\BOP\\Logs\\ConDirLogVM_1.txt";
    > my $LOG2="D:\\Prod_D\\BOP\\Logs\\ConDirLogVM_2.txt";
    >
    > my $LOG3="D:\\Prod_D\\BOP\\Logs\\ConDirLogVM_3.txt";
    > my $LOG4="D:\\Prod_D\\BOP\\Logs\\ConDirLogVM_4.txt";
    >
    > my $EXCONDIR="D:\\Prod_D\\BOP\\Scripts\\temp\\ConDirVM.cmd";


    You should use the forward slash (/) instead of the backslash (\) for
    path separators.

    > open (OUT,">>$LOG");


    You should *always* verify the success of open(). You should probably
    use a different name for the filehandle.

    > while(1) {
    >
    >
    > # Open the directory VM
    >
    > if( -d $dirVM ) {
    > opendir( VMDIR, $dirVM ) || die "Cannot open directory $dirVM $!";
    > }else{
    > print "Directory $dirVM does not exist. Exiting...\n";
    > exit;
    > }
    >
    > # Iterate through the directory VM
    >
    > opendir(VMDIR, $dirVM) || die "Cannot open directory $dirVM $!";


    Why open the directory twice. The whole if-else block is superfluous.

    > #open(VMDIR,"D:\\Prod_D\\BOP\\Data\\SMSDATA\\PCSWHSLE\\VM") || die
    > "Cannot open directory $dirVM $!";
    > #open(VMDIR,'dir "D:\Prod_D\BOP\Data\SMSDATA\PCSWHSLE\VM" |') || die;
    >
    > @FILES = readdir(VMDIR);
    >
    > #closedir(VMDIR);
    >
    > chomp (@FILES);


    chomp() is superfluous and *may* damage valid file names.

    > print "\n@FILES\n";
    >
    > foreach $FILE ( @FILES ) {
    >
    > if ($FILE !~ /^RU_VIRGIN_MOBILE_[0-9]_[0-9][0-9][0-9][0-9][0-9][0-9]
    > [0-9][0-9].*\.gz$/) {
    > #print "$FILE is not an EMBARQ product...\n";
    > goto sleeplabel;


    You don't need to use goto, you should use next and a continue block
    instead.

    > }else{
    >
    > chomp($FILE);


    Why chomp the same variable a second time? chomp() is superfluous and
    *may* damage valid file names.

    > print "\nFile is $FILE\n";
    >
    > print "\nBeginning Connect:Direct processing for VIRGIN MOBILE
    > customer file...\n";
    >
    > print OUT "\n$date $FILE\n";
    >
    > goto sleeplabel if (!$FILE);


    You don't need to use goto, you should use next and a continue block
    instead. How did $FILE get modified so that it became '0' or ''?

    > if (file_transfer_complete($FILE)) {


    One of the classic beginner mistakes. Your subroutine
    file_transfer_complete is using stat() on the file names but you need
    the complete path to properly stat() the file.

    > print "\nFound file $FILE\n";
    >
    >
    >
    >
    > open(IN, "$ConDir3\\send_triggerVM.pl");
    > open(OUT, ">$ConDir2\\tmp_sendVM.cdp");


    Why are you reusing the same filehandle name that you used for the log file?

    > while (<IN>) {
    > if (/ConDirFile/) {
    > s/ConDirFile/$dirVM$FILE/;


    You don't have to use the same regular expression twice.

    > }
    > print OUT $_;
    > }
    > close(OUT);
    > close(IN);
    >
    > print "First Connect:Direct pre-processing step passed...\n";
    >
    > "$ConDir2\\tmp_sendVM.cdp > D:\\Prod_D\\BOP\\scripts\\temp\\file";


    If you had warnings enabled you would have received a warning about a
    constant in void context here.

    > sleep 10;
    >
    > print "Second Connect:Direct pre-processing step passed...\n";
    >
    > system $EXCONDIR || errorexit(2, "\nConnect:Direct process failed");


    Because of the relatively high precedence of the || operator the
    errorexit() sub will never be called. If you fixed the precedence then
    errorexit() will only be called when system() succeeded.

    > print "\nConnect:Direct processing for VIRGIN MOBILE customer file
    > completed...\n";
    >
    > print OUT "\nConnect:Direct Processed for $date $FILE\n";
    >
    > # Send email to notify file has been C:D to mainframe
    >
    > my $machine = "PKSW1714";
    >
    > my $email = '';
    >
    > my $email2 = '';
    >
    > my $subject = "Connect:Direct Processing VIRGIN MOBILE: $FILE has
    > been sent to VIRGIN MOBILE node VSCPFTP01";
    >
    > my $body = " Hello, \n\n $FILE has been moved from $machine to
    > VSCPFTP01. \n\n Please contact $email2 with questions. \n\n Thanks, \n
    > \n IOP Connect:Direct Team\n\n";
    >
    > my $server = "10.214.13.55";


    $machine, $email, $email2 and $server are constants so why are they
    inside the loop?

    > my $msg = MIME::Lite->new(
    > From => '',
    > To => '',


    Why define variables for those strings and then not use them?

    > Subject => $subject,
    > Type => 'TEXT',
    > Data => $body
    > );
    >
    > #Use SMTP to send
    > MIME::Lite->send('smtp', $server, Timeout=>60);
    > sleep 30;
    > $msg->send;
    > open(OUT, ">>$LOG"); #reopen closed LOG


    If you had used a different name for the filehandle then you wouldn't
    have to do this.

    > print "\nEmail notification of Connect:Direct transfer sent...\n";
    >
    >
    > #sleeplabel2:
    > print"\n\n*******Waiting for VIRGIN MOBILE file processing to
    > complete*******\n\n";
    > sleep 50;
    >
    > # Rename the current process to done
    >
    > chomp($FILE);


    Why chomp the same variable a third time? chomp() is superfluous and
    *may* damage valid file names.

    > print "File is writable\n" if -w $FILE;


    You are using the file name only not the complete path so -w will not
    find the file you want.

    > $FILEDONE = $FILE . $doneExt;
    >
    > chomp($FILEDONE);


    Again, why are you chomp()ing the file name? Do you know what chomp() does?

    > print "filedone=$FILEDONE\n";
    >
    > #rename ("D:\\Prod_D\\BOP\\Data\\SMSDATA\\PCSWHSLE\\CD\\VM\
    > \RU_VIRGIN_MOBILE_1_20071130.007.gz", "D:\\Prod_D\\BOP\\Data\\SMSDATA\
    > \PCSWHSLE\\CD\\VM\\RU_VIRGIN_MOBILE_1_20071130.007.gz.done");
    > rename ($FILE, $FILEDONE);


    You are using the file name only not the complete path so rename() will
    not find the file you want.

    > #if (renamefiles($FILE)) {
    > print "\nFile successfully renamed: $FILEDONE\n" || errorexit(14,
    > "Could not rename $FILE");
    > #}
    >
    > #move ($FILE,$FILEDONE) || errorexit(9, "Unable to move $FILE");
    >
    > #copy ($FILE,$FILEDONE) || errorexit(12, "Unable to copy $FILE to
    > $FILEDONE");
    >
    > sleeplabel:


    You don't need to use goto, you should use next and a continue block
    instead.

    > print"\n\n*******Waiting for VIRGIN MOBILE Connect:Direct file*******
    > \n\n";
    > sleep 10;
    >
    >
    > #
    > # Begin Subroutines
    > #


    Why are you defining your subroutines *inside* the loop?

    > #
    > # Sub file_transfer_complete
    > #
    > # monitor a file for size changes over a brief period
    > #
    > # parm1 - file name
    > # parm2 - delay in seconds (optional)
    > #
    > sub file_transfer_complete {
    >
    > my $filename = shift;
    > my $waitTime = shift || 20;
    >
    > my $sizefirst = -s $filename; # initial file size
    > sleep $waitTime; # wait a while
    >
    > my $sizeDelta = -s $filename; #file size after wait


    You are using the file name only not the complete path so -s will not
    find the file you want.

    > if( $sizeDelta == $sizefirst ) {
    > print "transfer complete $filename 1: $sizefirst\t2: $sizeDelta" ;
    > return 1;
    > } else {
    > print "transfer incomplete $filename 1: $sizefirst\t2: $sizeDelta" ;
    > return 0;
    > }
    > }
    >
    >
    >
    > # Sub errorexit print error message to the log and return an error
    > code
    > #
    > sub errorexit {
    > my $returncode = shift;
    > my $message = shift;
    > open (OUT, ">>$LOG");


    If you had used a different name for the filehandle then you wouldn't
    have to do this.

    > print OUT "\n### ERROR $returncode ### $message";
    > exit ($returncode);
    > }
    >
    > # Sub Rename files to .done extension
    > #
    > sub renamefiles {
    >
    > my $file1 = shift;
    >
    > my $done = ".done";


    Why not use the $doneExt variable?

    > my $file2 = $file1 . $done;
    >
    > rename ($file1, $file2) || die "Cannot rename $file1\n";


    You are using the file name only not the complete path so rename() will
    not find the file you want.

    > }
    > }
    > }
    > }
    > }


    To sum up, here is the code with modifications that should work better
    (*UNTESTED*):

    #!/perl/bin/perl
    use warnings;
    use strict;
    #
    #NewAutoConDir.pl
    #Karin Walike
    #12.01.07
    #
    #Connect:Direct process automation for server PKSW1714
    #The script sleeps and wakes up to check and see if there is a file
    #has been loaded to the server for Connect:Direct to customer.
    #
    #
    #We currently have XX customers sending/receiving data to this node.
    #
    #Product list: xx, xx, xx, xx, xx,

    use MIME::Lite;

    my $dirVM = 'D:/Prod_D/BOP/Data/SMSDATA/PCSWHSLE/CD/VM';
    my $doneDir = 'D:/Prod_D/BOP/Data/SMSDATA/PCSWHSLE/CD/VM/DONE';
    my $ConDir2 = 'D:/Prod_D/BOP/Scripts/temp';
    my $ConDir3 = 'D:/Prod_D/BOP/scripts/triggerDir';
    my $LOG = 'D:/Prod_D/BOP/Logs/ConDirLogVM_1.txt';

    my $EXCONDIR = 'D:/Prod_D/BOP/Scripts/temp/ConDirVM.cmd';

    my $date = localtime;
    my $doneExt = '.done';
    my $machine = 'PKSW1714';
    my $email = '';
    my $email2 = '';
    my $server = '10.214.13.55';


    open my $LOGFH, '>>', $LOG or die "Cannot open '$LOG' $!";

    while ( 1 ) {
    # Open the directory VM
    # Iterate through the directory VM
    opendir my $VMDIR, $dirVM or die "Cannot open directory $dirVM $!";
    my @FILES = readdir $VMDIR;
    closedir $VMDIR;
    print "\n@FILES\n";
    for my $FILE ( @FILES ) {
    if ( $FILE !~ /^RU_VIRGIN_MOBILE_[0-9]_[0-9]{8}.*\.gz$/ ) {
    #print "$FILE is not an EMBARQ product...\n";
    next;
    }
    print "\nFile is $FILE\n";
    print "\nBeginning Connect:Direct processing for VIRGIN MOBILE
    customer file...\n";
    print $LOGFH "\n$date $FILE\n";
    next unless file_transfer_complete( "$dirVM/$FILE" );
    print "\nFound file $FILE\n";
    open my $IN, '<', "$ConDir3/send_triggerVM.pl" or die "Cannot
    open '$ConDir3/send_triggerVM.pl' $!";
    open my $OUT, '>', "$ConDir2/tmp_sendVM.cdp" or die "Cannot
    open '$ConDir2/tmp_sendVM.cdp' $!";
    while ( <$IN> ) {
    s/ConDirFile/$dirVM$FILE/;
    print $OUT $_;
    }
    close $OUT;
    close $IN;
    print "First Connect:Direct pre-processing step passed...\n";
    sleep 10;
    print "Second Connect:Direct pre-processing step passed...\n";
    system( $EXCONDIR ) == 0 or errorexit( 2, "\nConnect:Direct
    process failed" );
    print "\nConnect:Direct processing for VIRGIN MOBILE customer
    file completed...\n";
    print $LOGFH "\nConnect:Direct Processed for $date $FILE\n";
    # Send email to notify file has been C:D to mainframe
    my $subject = "Connect:Direct Processing VIRGIN MOBILE: $FILE
    has been sent to VIRGIN MOBILE node VSCPFTP01";
    my $body = <<BODY;
    Hello,

    $FILE has been moved from $machine to VSCPFTP01.

    Please contact $email2 with questions.

    Thanks,

    IOP Connect:Direct Team

    BODY
    my $msg = MIME::Lite->new(
    From => $email2,
    To => $email,
    Subject => $subject,
    Type => 'TEXT',
    Data => $body,
    );
    #Use SMTP to send
    MIME::Lite->send( 'smtp', $server, Timeout => 60 );
    sleep 30;
    $msg->send;
    print "\nEmail notification of Connect:Direct transfer sent...\n";
    print "\n\n*******Waiting for VIRGIN MOBILE file processing to
    complete*******\n\n";
    sleep 50;
    # Rename the current process to done
    print "File is writable\n" if -w "$dirVM/$FILE";
    my $FILEDONE = $FILE . $doneExt;
    print "filedone=$FILEDONE\n";
    rename "$dirVM/$FILE", "$dirVM/$FILEDONE" or die "Cannot rename
    '$dirVM/$FILE' to '$dirVM/$FILEDONE' $!";
    print "\nFile successfully renamed: $FILEDONE\n" or errorexit(
    14, "Could not rename $FILE" );
    }
    continue {
    print "\n\n*******Waiting for VIRGIN MOBILE Connect:Direct
    file*******\n\n";
    sleep 10;
    }
    }

    #
    # Begin Subroutines
    #

    # Sub file_transfer_complete
    #
    # monitor a file for size changes over a brief period
    #
    # parm1 - file name
    # parm2 - delay in seconds (optional)
    #
    sub file_transfer_complete {
    my $filename = shift;
    my $waitTime = shift || 20;
    my $sizefirst = -s $filename; # initial file size
    sleep $waitTime; # wait a while
    my $sizeDelta = -s $filename; #file size after wait
    if ( $sizeDelta == $sizefirst ) {
    print "transfer complete $filename 1: $sizefirst\t2: $sizeDelta";
    return 1;
    }
    else {
    print "transfer incomplete $filename 1: $sizefirst\t2: $sizeDelta";
    return 0;
    }
    }

    # Sub errorexit print error message to the log and return an error code
    #
    sub errorexit {
    my $returncode = shift;
    my $message = shift;
    print $LOGFH "\n### ERROR $returncode ### $message";
    exit $returncode;
    }

    __END__




    John
    --
    Perl isn't a toolbox, but a small machine shop where you
    can special-order certain sorts of tools at low cost and
    in short order. -- Larry Wall
    John W. Krahn, Jan 9, 2008
    #5
  6. kwalike57

    kwalike57 Guest

    Re: HELP! File Copy, Move and Rename will not work in my script!

    On Jan 8, 9:04 pm, "John W. Krahn" <> wrote:
    > kwalike57 wrote:
    > > On Jan 8, 3:33 pm, "John W. Krahn" <> wrote:

    >
    > >> Your second posting of the same problem and you still have not posted
    > >> any code.

    >
    > >> My crystal ball seems to think that you may have a problem with
    > >> directories, either incorrect names or missing completely?  Possibly on
    > >> line 42?

    >
    > It looks like my crystal ball is batting .500, correct problem, wrong
    > line number.
    >
    > > Here is the code...

    >
    > > #!/perl/bin/perl

    >
    > You should start off with the two pragmas:
    >
    > use warnings;
    > use strict;
    >
    > > #
    > > #NewAutoConDir.pl
    > > #Karin Walike
    > > #12.01.07
    > > #
    > > #Connect:Direct process automation for server PKSW1714
    > > #The script sleeps and wakes up to check and see if there is a file
    > > #has been loaded to the server for Connect:Direct to customer.
    > > #
    > > #
    > > #We currently have XX customers sending/receiving data to this node.
    > > #
    > > #Product list:  xx, xx, xx, xx, xx,

    >
    > > use MIME::Lite;
    > > use Cwd;
    > > use File::Copy;

    >
    > You don't appear to be using either Cwd or File::Copy?
    >
    > > my $date=localtime();

    >
    > > my $dirVM="D:\\Prod_D\\BOP\\Data\\SMSDATA\\PCSWHSLE\\CD\\VM\\";
    > > my $doneDir="D:\\Prod_D\\BOP\\Data\\SMSDATA\\PCSWHSLE\\CD\\VM\\DONE\
    > > \";

    >
    > > my $FILE;
    > > my @FILES;

    >
    > These should be declared inside the loop instead of here.
    >
    > > my $doneExt = ".done";

    >
    > > my $ConDir1="D:\\tools\\'Sterling Commerce'\\'CONNECT Direct v4.1'\
    > > \'Common Utilities'";
    > > my $ConDir2="D:\\Prod_D\\BOP\\Scripts\\temp";
    > > my $ConDir3="D:\\Prod_D\\BOP\\scripts\\triggerDir";

    >
    > > my $LOG="D:\\Prod_D\\BOP\\Logs\\ConDirLogVM_1.txt";
    > > my $LOG2="D:\\Prod_D\\BOP\\Logs\\ConDirLogVM_2.txt";

    >
    > > my $LOG3="D:\\Prod_D\\BOP\\Logs\\ConDirLogVM_3.txt";
    > > my $LOG4="D:\\Prod_D\\BOP\\Logs\\ConDirLogVM_4.txt";

    >
    > > my $EXCONDIR="D:\\Prod_D\\BOP\\Scripts\\temp\\ConDirVM.cmd";

    >
    > You should use the forward slash (/) instead of the backslash (\) for
    > path separators.
    >
    > > open (OUT,">>$LOG");

    >
    > You should *always* verify the success of open().  You should probably
    > use a different name for the filehandle.
    >
    > > while(1) {

    >
    > >    # Open the directory VM

    >
    > >    if( -d $dirVM ) {
    > >            opendir( VMDIR, $dirVM ) || die "Cannot open directory $dirVM $!";
    > >    }else{
    > >            print "Directory $dirVM does not exist. Exiting....\n";
    > >    exit;
    > >    }

    >
    > >    # Iterate through the directory VM

    >
    > >    opendir(VMDIR, $dirVM) || die "Cannot open directory $dirVM $!";

    >
    > Why open the directory twice.  The whole if-else block is superfluous.
    >
    > >    #open(VMDIR,"D:\\Prod_D\\BOP\\Data\\SMSDATA\\PCSWHSLE\\VM") || die
    > > "Cannot open directory $dirVM $!";
    > >    #open(VMDIR,'dir "D:\Prod_D\BOP\Data\SMSDATA\PCSWHSLE\VM" |') || die;

    >
    > >            @FILES = readdir(VMDIR);

    >
    > >    #closedir(VMDIR);

    >
    > >            chomp (@FILES);

    >
    > chomp() is superfluous and *may* damage valid file names.
    >
    > >            print "\n@FILES\n";

    >
    > >    foreach $FILE ( @FILES ) {

    >
    > >            if ($FILE !~ /^RU_VIRGIN_MOBILE_[0-9]_[0-9][0-9][0-9][0-9][0-9][0-9]
    > > [0-9][0-9].*\.gz$/) {
    > >                    #print "$FILE is not an EMBARQ product...\n";
    > >                    goto sleeplabel;

    >
    > You don't need to use goto, you should use next and a continue block
    > instead.
    >
    > >            }else{

    >
    > >            chomp($FILE);

    >
    > Why chomp the same variable a second time?  chomp() is superfluous and
    > *may* damage valid file names.
    >
    > >            print "\nFile is $FILE\n";

    >
    > >            print "\nBeginning Connect:Direct processing for VIRGIN MOBILE
    > > customer file...\n";

    >
    > >            print OUT "\n$date $FILE\n";

    >
    > >            goto sleeplabel if (!$FILE);

    >
    > You don't need to use goto, you should use next and a continue block
    > instead.  How did $FILE get modified so that it became '0' or ''?
    >
    > >                    if (file_transfer_complete($FILE)) {

    >
    > One of the classic beginner mistakes.  Your subroutine
    > file_transfer_complete is using stat() on the file names but you need
    > the complete path to properly stat() the file.
    >
    > >                    print "\nFound file $FILE\n";

    >
    > >    open(IN, "$ConDir3\\send_triggerVM.pl");
    > >    open(OUT, ">$ConDir2\\tmp_sendVM.cdp");

    >
    > Why are you reusing the same filehandle name that you used for the log file?
    >
    > >    while (<IN>) {
    > >            if (/ConDirFile/) {
    > >            s/ConDirFile/$dirVM$FILE/;

    >
    > You don't have to use the same regular expression twice.
    >
    > >            }
    > >            print OUT $_;
    > >            }
    > >            close(OUT);
    > >            close(IN);

    >
    > >    print "First Connect:Direct pre-processing step passed...\n";

    >
    > >    "$ConDir2\\tmp_sendVM.cdp > D:\\Prod_D\\BOP\\scripts\\temp\\file";

    >
    > If you had warnings enabled you would have received a warning about a
    > constant in void context here.
    >
    > > sleep 10;

    >
    > >    print "Second Connect:Direct pre-processing step passed...\n";

    >
    > >    system  $EXCONDIR || errorexit(2, "\nConnect:Direct process failed");

    >
    > Because of the relatively high precedence of the || operator the
    > errorexit() sub will never be called.  If you fixed the precedence then
    > errorexit() will only be called when system() succeeded.
    >
    > >    print "\nConnect:Direct processing for VIRGIN MOBILE customer file
    > > completed...\n";

    >
    > >    print OUT "\nConnect:Direct Processed for $date $FILE\n";

    >
    > >    # Send email to notify file has been C:D to mainframe

    >
    > >    my $machine = "PKSW1714";

    >
    > >    my $email = '';

    >
    > >    my $email2 = '';

    >
    > >    my $subject = "Connect:Direct Processing VIRGIN MOBILE: $FILE has
    > > been sent to VIRGIN MOBILE node VSCPFTP01";

    >
    > >    my $body = " Hello, \n\n $FILE has been moved from $machine to
    > > VSCPFTP01. \n\n Please contact $email2 with questions. \n\n Thanks, \n
    > > \n IOP Connect:Direct Team\n\n";

    >
    > >    my $server = "10.214.13.55";

    >
    > $machine, $email, $email2 and $server are constants so why are they
    > inside the loop?
    >
    > >    my $msg = MIME::Lite->new(
    > >            From => '',
    > >            To => '',

    >
    > Why define variables for those strings and then not use them?
    >
    > >            Subject => $subject,
    > >            Type => 'TEXT',
    > >            Data => $body
    > >    );

    >
    > >    #Use SMTP to send
    > >    MIME::Lite->send('smtp', $server, Timeout=>60);
    > >    sleep 30;
    > >    $msg->send;
    > >    open(OUT, ">>$LOG"); #reopen closed LOG

    >
    > If you had used a different name for the filehandle then you wouldn't
    > have to do this.
    >
    > >    print "\nEmail notification of Connect:Direct transfer sent...\n";

    >
    > >    #sleeplabel2:
    > >    print"\n\n*******Waiting for VIRGIN MOBILE file processing to
    > > complete*******\n\n";
    > >    sleep 50;

    >
    > >    # Rename the current process to done

    >
    > >    chomp($FILE);

    >
    > Why chomp the same variable a third time?  chomp() is superfluous and
    > *may* damage valid file names.
    >
    > >    print "File is writable\n" if -w $FILE;

    >
    > You are using the file name only not the complete path so -w will not
    > find the file you want.
    >
    > >    $FILEDONE = $FILE . $doneExt;

    >
    > >    chomp($FILEDONE);

    >
    > Again, why are you chomp()ing the file name?  Do you know what chomp() does?
    >
    > >    print "filedone=$FILEDONE\n";

    >
    > >    #rename ("D:\\Prod_D\\BOP\\Data\\SMSDATA\\PCSWHSLE\\CD\\VM\
    > > \RU_VIRGIN_MOBILE_1_20071130.007.gz", "D:\\Prod_D\\BOP\\Data\\SMSDATA\
    > > \PCSWHSLE\\CD\\VM\\RU_VIRGIN_MOBILE_1_20071130.007.gz.done");
    > >    rename ($FILE, $FILEDONE);

    >
    > You are using the file name only not the complete path so rename() will
    > not find the file you want.
    >
    > >    #if (renamefiles($FILE)) {
    > >                    print "\nFile successfully renamed: $FILEDONE\n" || errorexit(14,
    > > "Could not rename $FILE");
    > >    #}

    >
    > >    #move ($FILE,$FILEDONE) || errorexit(9, "Unable to move $FILE");

    >
    > >    #copy ($FILE,$FILEDONE) || errorexit(12, "Unable to copy $FILE to
    > > $FILEDONE");

    >
    > >    sleeplabel:

    >
    > You don't need to use goto, you should use next and a continue block
    > instead.
    >
    > >    print"\n\n*******Waiting for VIRGIN MOBILE Connect:Direct file*******
    > > \n\n";
    > >    sleep 10;

    >
    > > #
    > > # Begin Subroutines
    > > #

    >
    > Why are you defining your subroutines *inside* the loop?
    >
    > > #
    > > # Sub file_transfer_complete
    > > #
    > > # monitor a file for size changes over a brief period
    > > #
    > > # parm1 - file name
    > > # parm2 - delay in seconds (optional)
    > > #
    > > sub file_transfer_complete {

    >
    > > my $filename = shift;
    > > my $waitTime = shift || 20;

    >
    > > my $sizefirst = -s $filename;      # initial file size
    > > sleep $waitTime;           # wait a while

    >
    > > my $sizeDelta = -s $filename;      #file size after wait

    >
    > You are using the file name only not the complete path so -s will not
    > find the file you want.
    >
    > > if( $sizeDelta == $sizefirst ) {
    > >    print "transfer complete $filename 1: $sizefirst\t2: $sizeDelta" ;
    > >    return 1;
    > > } else {
    > >    print "transfer incomplete $filename 1: $sizefirst\t2: $sizeDelta" ;
    > >    return 0;
    > >    }
    > > }

    >
    > > # Sub errorexit print error message to the log and return an error
    > > code
    > > #
    > > sub errorexit {
    > >    my $returncode = shift;
    > >    my $message = shift;
    > >    open (OUT, ">>$LOG");

    >
    > If you had used a different name for the filehandle then you wouldn't
    > have to do this.
    >
    > >    print OUT "\n### ERROR $returncode ### $message";
    > >    exit ($returncode);
    > > }

    >
    > > # Sub Rename files to .done extension
    > > #
    > > sub renamefiles {

    >
    > >    my $file1 = shift;

    >
    > >    my $done = ".done";

    >
    > Why not use the $doneExt variable?
    >
    > >    my $file2 = $file1 . $done;

    >
    > >    rename ($file1, $file2) || die "Cannot rename $file1\n";

    >
    > You are using the file name only not the complete path so rename() will
    > not find the file you want.
    >
    > > }
    > > }
    > > }
    > > }
    > > }

    >
    > To sum up, here is the code with modifications that should work better
    > (*UNTESTED*):
    >
    > #!/perl/bin/perl
    > use warnings;
    > use strict;
    > #
    > #NewAutoConDir.pl
    > #Karin Walike
    > #12.01.07
    > #
    > #Connect:Direct process automation for server PKSW1714
    > #The script sleeps and wakes up to check and see if there is a file
    > #has been loaded to the server for Connect:Direct to customer.
    > #
    > #
    > #We currently have XX customers sending/receiving data to this node.
    > #
    > #Product list:  xx, xx, xx, xx, xx,
    >
    > use MIME::Lite;
    >
    > my $dirVM    = 'D:/Prod_D/BOP/Data/SMSDATA/PCSWHSLE/CD/VM';
    > my $doneDir  = 'D:/Prod_D/BOP/Data/SMSDATA/PCSWHSLE/CD/VM/DONE';
    > my $ConDir2  = 'D:/Prod_D/BOP/Scripts/temp';
    > my $ConDir3  = 'D:/Prod_D/BOP/scripts/triggerDir';
    > my $LOG      = 'D:/Prod_D/BOP/Logs/ConDirLogVM_1.txt';
    >
    > my $EXCONDIR = 'D:/Prod_D/BOP/Scripts/temp/ConDirVM.cmd';
    >
    > my $date     = localtime;
    > my $doneExt  = '.done';
    > my $machine  = 'PKSW1714';
    > my $email    = '';
    > my $email2   = '';
    > my $server   = '10.214.13.55';
    >
    > open my $LOGFH, '>>', $LOG or die "Cannot open '$LOG' $!";
    >
    > while ( 1 ) {
    >      # Open the directory VM
    >      # Iterate through the directory VM
    >      opendir my $VMDIR, $dirVM or die "Cannot open directory $dirVM $!";
    >      my @FILES = readdir $VMDIR;
    >      closedir $VMDIR;
    >      print "\n@FILES\n";
    >      for my $FILE ( @FILES ) {
    >          if ( $FILE !~ /^RU_VIRGIN_MOBILE_[0-9]_[0-9]{8}.*\.gz$/) {
    >              #print "$FILE is not an EMBARQ product...\n";
    >              next;
    >              }
    >          print "\nFile is $FILE\n";
    >          print "\nBeginning Connect:Direct processing for VIRGINMOBILE
    > customer file...\n";
    >          print $LOGFH "\n$date $FILE\n";
    >          next unless file_transfer_complete( "$dirVM/$FILE" );
    >          print "\nFound file $FILE\n";
    >          open my $IN,  '<', "$ConDir3/send_triggerVM.pl" or die "Cannot
    > open '$ConDir3/send_triggerVM.pl' $!";
    >          open my $OUT, '>', "$ConDir2/tmp_sendVM.cdp"    or die "Cannot
    > open '$ConDir2/tmp_sendVM.cdp' $!";
    >          while ( <$IN> ) {
    >              s/ConDirFile/$dirVM$FILE/;
    >              print $OUT $_;
    >              }
    >          close $OUT;
    >          close $IN;
    >          print "First Connect:Direct pre-processing step passed....\n";
    >          sleep 10;
    >          print "Second Connect:Direct pre-processing step passed....\n";
    >          system( $EXCONDIR ) == 0 or errorexit( 2, "\nConnect:Direct
    > process failed" );
    >          print "\nConnect:Direct processing for VIRGIN MOBILE customer
    > file completed...\n";
    >          print $LOGFH "\nConnect:Direct Processed for $date $FILE\n";
    >          # Send email to notify file has been C:D to mainframe
    >          my $subject = "Connect:Direct Processing VIRGIN MOBILE: $FILE
    > has been sent to VIRGIN MOBILE node VSCPFTP01";
    >          my $body = <<BODY;
    >   Hello,
    >
    >   $FILE has been moved from $machine to VSCPFTP01.
    >
    >   Please contact $email2 with questions.
    >
    >   Thanks,
    >
    >   IOP Connect:Direct Team
    >
    > BODY
    >          my $msg = MIME::Lite->new(
    >              From    => $email2,
    >              To      => $email,
    >              Subject => $subject,
    >              Type    => 'TEXT',
    >              Data    => $body,
    >              );
    >          #Use SMTP to send
    >          MIME::Lite->send( 'smtp', $server, Timeout => 60 );
    >          sleep 30;
    >          $msg->send;
    >          print "\nEmail notification of Connect:Direct transfer sent...\n";
    >          print "\n\n*******Waiting for VIRGIN MOBILE file processing to
    > complete*******\n\n";
    >          sleep 50;
    >          # Rename the current process to done
    >          print "File is writable\n" if -w "$dirVM/$FILE";
    >          my $FILEDONE = $FILE . $doneExt;
    >          print "filedone=$FILEDONE\n";
    >          rename "$dirVM/$FILE", "$dirVM/$FILEDONE" or die "Cannot rename
    > '$dirVM/$FILE' to '$dirVM/$FILEDONE' $!";
    >          print "\nFile successfully renamed: $FILEDONE\n" or errorexit(
    > 14, "Could not rename $FILE" );
    >          }
    >      continue {
    >          print "\n\n*******Waiting for VIRGIN MOBILE Connect:Direct
    > file*******\n\n";
    >          sleep 10;
    >          }
    >      }
    >
    > #
    > # Begin Subroutines
    > #
    >
    > # Sub file_transfer_complete
    > #
    > # monitor a file for size changes over a brief period
    > #
    > # parm1 - file name
    > # parm2 - delay in seconds (optional)
    > #
    > sub file_transfer_complete {
    >      my $filename = shift;
    >      my $waitTime = shift || 20;
    >      my $sizefirst = -s $filename;    # initial file size
    >      sleep $waitTime;                 # wait a while
    >      my $sizeDelta = -s $filename;    #file size after wait
    >      if ( $sizeDelta == $sizefirst ) {
    >          print "transfer complete $filename 1: $sizefirst\t2: $sizeDelta";
    >          return 1;
    >          }
    >      else {
    >          print "transfer incomplete $filename 1: $sizefirst\t2: $sizeDelta";
    >          return 0;
    >          }
    >      }
    >
    > # Sub errorexit print error message to the log and return an error code
    > #
    > sub errorexit {
    >      my $returncode = shift;
    >      my $message    = shift;
    >      print $LOGFH "\n### ERROR $returncode ### $message";
    >      exit $returncode;
    >      }
    >
    > __END__
    >
    > John
    > --
    > Perl isn't a toolbox, but a small machine shop where you
    > can special-order certain sorts of tools at low cost and
    > in short order.                            -- Larry Wall


    Thanks for all of the thought and advice you have put into this
    response. I will give it a try and see if I get anywhere. Since this
    posting I have been testing with a number of different changes, all no
    good so far.

    Thanks again,

    Karin Walike
    kwalike57, Jan 10, 2008
    #6
  7. Re: HELP! File Copy, Move and Rename will not work in my script!

    kwalike57 <> wrote:

    > Subject: HELP! File Copy, Move and Rename will not work in my script!



    [ snip over 500 lines of quoted text ]


    > Thanks for all of the thought and advice you have put into this
    > response. I will give it a try and see if I get anywhere. Since this
    > posting I have been testing with a number of different changes, all no
    > good so far.



    Did we really need to see the 500 lines that your 4 lines of new text
    were referring to?

    Have you seen the Posting Guidelines that are posted here frequently?

    You should do that soon before your posts become widely invisible...


    --
    Tad McClellan
    email: perl -le "print scalar reverse qq/moc.noitatibaher\100cmdat/"
    Tad J McClellan, Jan 10, 2008
    #7
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    26
    Views:
    2,083
    Roland Pibinger
    Sep 1, 2006
  2. shapper

    Rename and Move File

    shapper, Feb 12, 2008, in forum: ASP .Net
    Replies:
    1
    Views:
    404
    Misbah Arefin
    Feb 12, 2008
  3. cliffyg
    Replies:
    0
    Views:
    446
    cliffyg
    Mar 6, 2008
  4. Eduardo78
    Replies:
    0
    Views:
    237
    Eduardo78
    Nov 3, 2005
  5. Mrmaster Mrmaster

    Which is more expensive Rename or Move?

    Mrmaster Mrmaster, Jun 16, 2009, in forum: Ruby
    Replies:
    8
    Views:
    148
    Matthew K. Williams
    Jun 17, 2009
Loading...

Share This Page