Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   Perl Misc (http://www.velocityreviews.com/forums/f67-perl-misc.html)
-   -   HELP! File Copy, Move and Rename will not work in my script! (http://www.velocityreviews.com/forums/t905993-help-file-copy-move-and-rename-will-not-work-in-my-script.html)

kwalike57 01-08-2008 11:20 PM

HELP! File Copy, Move and Rename will not work in my script!
 
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

John W. Krahn 01-08-2008 11:33 PM

Re: HELP! File Copy, Move and Rename will not work in my script!
 
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

J. Gleixner 01-08-2008 11:44 PM

Re: HELP! File Copy, Move and Rename will not work in my script!
 
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.

kwalike57 01-09-2008 12:17 AM

Re: HELP! File Copy, Move and Rename will not work in my script!
 
On Jan 8, 3:33*pm, "John W. Krahn" <some...@example.com> 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\\ConDirV M.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\\PCSWH SLE\\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 = 'IOP-ITSupport@sprint.com';

my $email2 = 'CD.Rom@sprint.com';

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 => 'CD.Rom@sprint.com',
To => 'IOP-ITSupport@sprint.com',
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";
}
}
}
}
}

John W. Krahn 01-09-2008 05:04 AM

Re: HELP! File Copy, Move and Rename will not work in my script!
 
kwalike57 wrote:
> On Jan 8, 3:33 pm, "John W. Krahn" <some...@example.com> 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\\ConDirV M.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\\PCSWH SLE\\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 = 'IOP-ITSupport@sprint.com';
>
> my $email2 = 'CD.Rom@sprint.com';
>
> 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 => 'CD.Rom@sprint.com',
> To => 'IOP-ITSupport@sprint.com',


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 = 'IOP-ITSupport@sprint.com';
my $email2 = 'CD.Rom@sprint.com';
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

kwalike57 01-10-2008 12:19 AM

Re: HELP! File Copy, Move and Rename will not work in my script!
 
On Jan 8, 9:04*pm, "John W. Krahn" <some...@example.com> wrote:
> kwalike57 wrote:
> > On Jan 8, 3:33 pm, "John W. Krahn" <some...@example.com> 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\\ConDirV M.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\\PCSWH SLE\\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 = 'IOP-ITSupp...@sprint.com';

>
> > * *my $email2 = 'CD....@sprint.com';

>
> > * *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 => 'CD....@sprint.com',
> > * * * * * *To => 'IOP-ITSupp...@sprint.com',

>
> 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 * *= 'IOP-ITSupp...@sprint.com';
> my $email2 * = 'CD....@sprint.com';
> 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

Tad J McClellan 01-10-2008 03:38 AM

Re: HELP! File Copy, Move and Rename will not work in my script!
 
kwalike57 <karinwalike@comcast.net> 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/"


All times are GMT. The time now is 02:01 AM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.