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...
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