Question

My script:

#!/usr//bin/perl
#
# Script to balance accounts between servers
# By Philip Gabrielsen
#    
use strict;
use warnings;    
START:
print "\nZimbra account moving script\n";
print "First we will collect data from Zimbra, this may take a while.\n\n";

my %accounts;
DATACOLLECT:
print "Collecting Zimbra mailbox server(s)... ";
my $servers = `zmprov gas mailbox`;
print "OK\n";

print "Collecting numbers of accounts per server... ";
foreach my $server (split(/\n/, $servers)) {
  $accounts{$server} = `zmprov -l gaa -s $server|wc -l`;
}
print "OK\n";

foreach my $server (keys %accounts) {
  print "\nServer $server with ". $accounts{$server} ." accounts\n";
}

print "TEST, is total number of accounts good?";
$accounts{'total'} = 0;
foreach my $server1 (keys %accounts) {
  $accounts{'total'} = $accounts{'total'} + $accounts{$server1};
  print "\nAdded $accounts{$server1} and total is now $accounts{'total'}";
}
print "\nTotal number of accounts: $accounts{'total'}\n";

Output: [zimbra@snake tmp]$ perl accounts.pl

Zimbra account moving script
First we will collect data from Zimbra, this may take a while.

Collecting Zimbra mailbox server(s)... OK
Collecting numbers of accounts per server... OK

Server snake with 363
 accounts

Server tiger with 431
 accounts

Server lion with 273
 accounts
TEST, is total number of accounts good?
Added 363
 and total is now 363
Added 431
 and total is now 794
Added [zimbra@tiberius tmp]$ perl accounts.pl

Zimbra account moving script
First we will collect data from Zimbra, this may take a while.

Collecting Zimbra mailbox server(s)... OK
Collecting numbers of accounts per server... OK

Server titus.zimbra.h.bitbit.net with 363
 accounts

Server tiberius.zimbra.h.bitbit.net with 431
 accounts

Server otho.zimbra.h.bitbit.net with 273
 accounts
TEST, is total number of accounts good?
Added 363
 and total is now 363
Added 431
 and total is now 794
Added 1588 and total is now 1588
Added 273
 and total is now 1861
Total number of accounts: 1861 and total is now 1588
Added 273
 and total is now 1861
Total number of accounts: 1861

As first seen, when listing account from each server, the correct number is displayed, but the last part, when i want to add all $accounts into a total value, the number 1588 pops up, this should been 273...

Was it helpful?

Solution

I have to admit, for a while you had me stumped. But then I realized that this code is not correct:

$accounts{'total'} = 0;                 # here you add a key to the serverlist
foreach my $server1 (keys %accounts) {  # here you list all keys
  $accounts{'total'} = $accounts{'total'} + $accounts{$server1};
  print "\nAdded $accounts{$server1} and total is now $accounts{'total'}";
}

Because the key total is one of the keys in the same hash:

titus.zimbra.h.bitbit.net
tiberius.zimbra.h.bitbit.net
otho.zimbra.h.bitbit.net 
total

So when you reach the point in the list for key total, you see that the total doubles, from 794 to 1588.

The answer would be to not use the same hash for storing your sum. In fact, why use a hash at all?

my $total = 0;                    # independent scalar 
foreach my $server1 (keys %accounts) {
  $total += $accounts{$server1};
  print "\nAdded $accounts{$server1} and total is now $total";
}

Also worth noting is that you say in the comments that chomp turns all your numbers into 1. You are probably using chomp wrong, which is a common beginner mistake.

$count = chomp($count);      # WRONG! chomp returns number of newlines removed
chomp($count);               # Correct. chomp modifies its argument variable

You might ask what good it is for chomp to return the number of newlines removed, and the answer is that it can also be used on arrays and hashes:

my $removed = chomp(@array); # See how many newlines were removed 

OTHER TIPS

You neeed to chomp() your input lines after reading from Zimbra commands - that's why there is a newline before "...and total is now".

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top