For Programmers: Free Programming Magazines  


Home > Archive > PERL Beginners > May 2007 > logic not working









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author logic not working
Tony Heal

2007-05-20, 6:59 pm

OK I am probably missing something stupid, but I can not get this to work. The output should be 'Daily-{day of
w)-{MMM}-{DD}-{YYYY}' for Sunday thru Friday and 'Wly-{1|2|3}-{day of w)-{MMM}-{DD}-{YYYY} for Saturday and
every fourth Saturday should start rotating months 'Month-{1|2|3}-{day of w)-{MMM}-{DD}-{YYYY}



Anyone got any ideas?



Oh, there is some code at the front that changes the system date from May 1 to 31



Thanks





Tony





#!/usr/bin/perl

use warnings;

use strict;

my $today = `date +%m%d%H%M`;

my $count = "501";

while ($count lt 532){

my $that = "0$count" . "2100";

system("date $that");

my $backupBaseDir = '/gfsbackup';

my $logFile = "$backupBaseDir\/gfs_backup.log";

my $scpCMD = 'scp -i /usr/backup/.ssh/haddock';

my $backupDir = gfsBackup();

my @ePaceServers = ("silverfish", "catfish", "bonefish");

if ( ! -d $backupBaseDir )

{

mkdir $backupBaseDir;

}

sub gfsBackup

{

my ($sec,$min,$hour,$mday,$mon,$yearOffset,
$wday,$yday,$isdst)=localtime(time);

my $year = $yearOffset + 1900;

my ($wsec,$wmin,$whour,$wmday,$
wmon,$wyearOffset,$wwday,$wy
day,$wisdst)=localtime(time -
(84600 * 8));

my $wyear = $wyearOffset + 1900;

my ($msec,$mmin,$mhour,$mmday,$mmon,$myearO
ffset,$mwday,$myday,$misdst)=localtime(t
ime - (84600 * 29));

my $myear = $yearOffset + 1900;

my $w = int($yday/7);

my $sevendays = (time - (84600 * 7));

my @days = ("Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday");

my @months = ("Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec");

my ($directory, @dir, $month, $gfsDir, $DatedgfsDir, $monthDirectory, @monthDir, $lastW, $dirtemp);

if ( $days[$wday] =~ "Saturday" )

{

opendir (DIR, $backupBaseDir);

my @readdir = readdir(DIR);

closedir(DIR);

while (<@readdir> )

{

$directory = $_;

print "directory = $directory\n";

if ( $directory =~ "$months[$wmon]-$wmday-$wyear" )

{

@dir = split( /-/, $directory);

if ( $dir[0] =~ "Monthly" )

{

$gfsDir = "Wly-1";

}

if ( $dir[0] =~ "Wly" )

{

if ( $dir[1] lt 3 )

{

my $wcount = $dir[1] + 1;

$gfsDir = "Wly-$wcount";

}

if ( $dir[1] eq 3 )

{

my $monthcount = `ls $backupBaseDir | grep
"$months[$mmon]-$mmday-$myear" | cut -d- -f2`;

if ( $monthcount eq "13" )

{

$gfsDir = "Monthly-1";

}

else

{

$monthcount++;

$gfsDir = "Monthly-$monthcount";

}

}

}

last;

}

}

}

elsif ( $days[$wday] =~ "Saturday" )

{

$gfsDir = "Wly-1";

last;

}

if ( ! $gfsDir )

{

$gfsDir = "Daily-$days[$wday]-$months[$mon]-$mday-$year";

mkdir "$backupBaseDir/$gfsDir";

chdir "$backupBaseDir/$gfsDir";

return $gfsDir;

}

else

{

$DatedgfsDir = "$gfsDir-$days[$wday]-$months[$mon]-$mday-$year";

mkdir "$backupBaseDir/$DatedgfsDir";

chdir "$backupBaseDir/$DatedgfsDir";

$gfsDir = $DatedgfsDir;

return $gfsDir;

}

}

$count++;}




Paul Lalli

2007-05-20, 6:59 pm

On May 20, 12:21 pm, t...@pace2020.com (Tony Heal) wrote:
> OK I am probably missing something stupid, but I can not get this to work.


Could you possibly describe in what way it "does not work", rather
than asking us to figure it out based on that massive amount of code?

Paul Lalli

Celice

2007-05-21, 7:58 am

Tony Heal wrote:
>
> OK I am probably missing something stupid, but I can not get this to work.
> The output should be 'Daily-{day of w)-{MMM}-{DD}-{YYYY}' for Sunday
> thru Friday and 'Wly-{1|2|3}-{day of w)-{MMM}-{DD}-{YYYY} for
> Saturday and every fourth Saturday should start rotating months
> 'Month-{1|2|3}-{day of w)-{MMM}-{DD}-{YYYY}
>
> Anyone got any ideas?
>
> Oh, there is some code at the front that changes the system date from May 1
> to 31


Hi Tony

I'm sorry I'm afraid there's so little chance of getting that code working I'm
not even going to try. I spent half an hour trying to understand how it was
structured and what you were trying to do and had to give up. It looks to me
like you've written the whole thing in one go and then started to get it to
work, which isn't the way to go about even simple coding problems: you need to
make software work in small steps at a time and gradually approach the final
solution, all the time with a working partial solution.

To try and get you started here are a few pointers, with most of the code
removed so that the problems are apparent:

You have written

while ($count lt 532){

my $backupDir = gfsBackup();

sub gfsBackup

}

$count++;}


which I didn't even know would compile. Take the subroutine out of the while
loop or there's really no point in having it there.

Oh, and it should be

while ($count < 532) {
}

otherwise you're comparing text instead of numbers.


The lines

opendir (DIR, $backupBaseDir);
my @readdir = readdir(DIR);
closedir(DIR);

while (<@readdir> )
{
}

are wrong, and the most obvious fix is to put

foreach (@readdir) {

}

but I don't know if the code around this will work either way.


You have

if ( $days[$wday] =~ "Saturday" )
{
}
elsif ( $days[$wday] =~ "Saturday" )
{
}

which is clearly wrong, and it isn't obvious what you meant. Furthermore these
two conditional lines are indented by different amounts, making me think your
nesting isn't what you think it is. Use less whitespace in your code and
carefully align matching braces.

Finally, stuff like

if ($days[$wday] =~ "Saturday")

should be

if ($days[$wday] eq 'Saturday')

although this won't actually stop it working.

I think that's all I can do for you for now. Please try to clarify your code
and make it look as if it ought to work before you try it. You are doomed to
failure if you throw together a few approximate source lines and try to hack
them until the output looks right.

Good luck,

Rob

John W. Krahn

2007-05-22, 6:59 pm

Tony Heal wrote:

> OK I am probably missing something stupid, but I can not get this to work.
> The output should be 'Daily-{day of w)-{MMM}-{DD}-{YYYY}' for Sunday
> thru Friday and 'Wly-{1|2|3}-{day of w)-{MMM}-{DD}-{YYYY} for
> Saturday and every fourth Saturday should start rotating months
> 'Month-{1|2|3}-{day of w)-{MMM}-{DD}-{YYYY}
>
> Anyone got any ideas?
>
> Oh, there is some code at the front that changes the system date from May
> 1 to 31




[ Whitespace adjusted to aid legibility. ]

> #!/usr/bin/perl
> use warnings;
> use strict;
> my $today = `date +%m%d%H%M`;


Why call an external program to do something that you can do in perl:

my @today = ( localtime )[ 4, 3, 2, 1 ];
$today[ 0 ]++;
my $today = sprintf '%02d%02d%02d%02d', @today;

Or:

use POSIX 'strftime';
my $today = strftime '%m%d%H%M', localtime;


> my $count = "501";
> while ( $count lt 532 ) {
> my $that = "0$count" . "2100";


Do you want to use strings or numbers?

For strings:

for ( '0501' .. '0531' ) {
my $that = $_ . '2100';

For numbers:

for ( 501 .. 531 ) {
my $that = sprintf '%04d2100', $_;


> system("date $that");


The date command changes the *system* date! In other words, this change
will effect all other programs running on your system. Do you really want
to do that?


> my $backupBaseDir = '/gfsbackup';
> my $logFile = "$backupBaseDir\/gfs_backup.log";


You don't have to escape the slash in a double quoted string.

> my $scpCMD = 'scp -i /usr/backup/.ssh/haddock';


And here you have a double quoted string without escaped slashes.

> my $backupDir = gfsBackup();
> my @ePaceServers = ("silverfish", "catfish", "bonefish");
> if ( ! -d $backupBaseDir )
> {
> mkdir $backupBaseDir;
> }
> sub gfsBackup


Subroutines in perl are package variables so there is no point defining them
inside a loop.


> {
> my ( $sec, $min, $hour, $mday, $mon, $yearOffset, $wday, $yday,

$isdst ) = localtime( time );
> my $year = $yearOffset + 1900;
> my ( $wsec, $wmin, $whour, $wmday, $wmon,

$wyearOffset, $wwday, $wyday, $wisdst ) = localtime( time - (
84600 * 8 ) );
> my $wyear = $wyearOffset + 1900;
> my ( $msec, $mmin, $mhour, $mmday, $mmon, $myearOffset, $mwday,

$myday, $misdst ) = localtime( time - ( 84600 * 29 ) );
> my $myear = $yearOffset + 1900;


Shouldn't that be:

my $myear = $myearOffset + 1900;

> my $w = int( $yday / 7 );
> my $sevendays = ( time - ( 84600 * 7 ) );
> my @days =

( "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" );
> my @months =

( "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" );
> my ( $directory, @dir, $month, $gfsDir, $DatedgfsDir, $monthDirectory,

@monthDir, $lastW, $dirtemp );

The only variable you need to declare at this level is:

my $gfsDir;

> if ( $days[$wday] =~ "Saturday" )


Why not more simply:

if ( $wday == 6 ) # 6 = Saturday

> {
> opendir( DIR, $backupBaseDir );


You should *always* verify that the directory opened correctly:

opendir DIR, $backupBaseDir or die "Cannot open '$backupBaseDir' $!";


> my @readdir = readdir( DIR );
> closedir( DIR );
> while ( <@readdir> )


That is the same as:

while ( glob "@readdir" )

Which means that you are globbing the file names that you just got from
readdir so you are now reading the directory contents a second time. This
will *not* work correctly if any of the file names contain whitespace or
glob meta-characters.

What you want is:

for my $directory ( @readdir )


> {
> $directory = $_;
> print "directory = $directory\n";
> if ( $directory =~ "$months[$wmon]-$wmday-$wyear" )
> {
> @dir = split( /-/, $directory );


my @dir = split( /-/, $directory );


> if ( $dir[0] =~ "Monthly" )


Shouldn't that be:

if ( $dir[0] eq 'Monthly' )


> {
> $gfsDir = "Wly-1";
> }
> if ( $dir[0] =~ "Wly" )


Shouldn't that be:

if ( $dir[0] eq 'Wly' )


> {
> if ( $dir[1] lt 3 )


if ( $dir[1] < 3 )


> {
> my $wcount = $dir[ 1 ] + 1;
> $gfsDir = "Wly-$wcount";
> }
> if ( $dir[1] eq 3 )


if ( $dir[1] == 3 )


> {
> my $monthcount = `ls $backupBaseDir |

grep "$months[$mmon]-$mmday-$myear" | cut -d- -f2`;

No need to call three external programs to do what you can do in perl:

my ( $monthcount ) = map +( split /-/ )[ 1 ],
<$backupBaseDir/*$months[$mmon]-$mmday-$myear*>;


> if ( $monthcount eq "13" )


This will *never* match! If the backquotes return '13' then $monthcount
will contain "13\n" and it will not match '13'.


> {
> $gfsDir = "Monthly-1";
> }
> else
> {
> $monthcount++;
> $gfsDir = "Monthly-$monthcount";
> }
> }
> }
> last;
> }
> }
> }
> elsif ( $days[$wday] =~ "Saturday" )


The if clause for this elsif is:

if ( $days[$wday] =~ "Saturday" )

Which is *exactly* the same so this elsif block will *never* execute.


> {
> $gfsDir = "Wly-1";
> last;


At this point you are not inside a loop so using last is an error.


> }
> if ( ! $gfsDir )
> {
> $gfsDir = "Daily-$days[$wday]-$months[$mon]-$mday-$year";
> mkdir "$backupBaseDir/$gfsDir";
> chdir "$backupBaseDir/$gfsDir";
> return $gfsDir;
> }
> else
> {
> $DatedgfsDir = "$gfsDir-$days[$wday]-$months[$mon]-$mday-$year";
> mkdir "$backupBaseDir/$DatedgfsDir";
> chdir "$backupBaseDir/$DatedgfsDir";
> $gfsDir = $DatedgfsDir;
> return $gfsDir;
> }


You can remove a lot of duplicate code like this:

$gfsDir = ( $gfsDir ?
$gfsDir : 'Daily' ) . "-$days[$wday]-$months[$mon]-$mday-$year";
mkdir "$backupBaseDir/$gfsDir" or die "Cannot
mkdir '$backupBaseDir/$gfsDir' $!";
chdir "$backupBaseDir/$gfsDir" or die "Cannot
chdir '$backupBaseDir/$gfsDir' $!";
return $gfsDir;


> }
> $count++;}




John
Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com