Perl- последующие итерации хэша неправильно устанавливают / возвращают данные

#perl #hash

#perl #хэш

Вопрос:

Итак. Интересная проблема.

Я создаю мастер-скрипт для оценки некоторых выходных данных powershell буквально на сотнях серверов, надеясь сэкономить время на просмотр этих массивных текстовых файлов для оценки конфигураций сервера. С этой целью в этом разделе скрипта проверяется вывод настроек файла журнала (пример данных ниже):

 System_GroupPolicyResults::         Audit Policy
System_GroupPolicyResults::         ------------
System_GroupPolicyResults::             GPO: Default Domain Policy
System_GroupPolicyResults::                 Policy:            AuditObjectAccess
System_GroupPolicyResults::                 Computer Setting:  Failure
System_GroupPolicyResults:: 
System_GroupPolicyResults::             GPO: Logging - Auditing
System_GroupPolicyResults::                 Policy:            AuditPolicyChange
System_GroupPolicyResults::                 Computer Setting:  Success, Failure
System_GroupPolicyResults:: 
System_GroupPolicyResults::             GPO: Logging - Auditing
System_GroupPolicyResults::                 Policy:            AuditObjectAccess
System_GroupPolicyResults::                 Computer Setting:  Success, Failure
  

Эта небольшая часть perlscript отвечает за разбиение этого и создание отчетов по этим полям — все, что я действительно делаю, это читаю регулярное выражение, извлекаю некоторые значения и отмечаю, соответствует ли сервер нашим ожиданиям (в этом случае мы должны увидеть «Успех, сбой» для всех этих настроек (привет, аудит PCI. Это то, что есть).. и затем форматируют выходные данные в таблице.

             while ($serverdata =~ /System_GroupPolicyResults::s Policy:s (Auditw )n.*Compu.*:s (.*w)/g) {
                $logsettings{$1} = $2;
                $setflag = $1;
                if ($logsettings{$setflag} =~ /Success,/) {
                    $logcheck{$setflag} = "Good";
                } else {
                    $logcheck{$setflag} = "FAIL";
                    if ($caughtflag == 0) {
                        push @FailedAuditGPO, $srvname;
                        $caughtflag  ;
                    }
                }
            }
        #Let's report this:
        
        #First, let's clean up the bad setting that creeps in:
            delete $logsettings{AuditPrivilege};
            print "tGPO Audit Settings - $auditsettingsGPO:n";
            printf ("%-20s %-20s %-10sn","Audit Value:","Current Setting:","Status:");
            foreach $type (keys %logsettings) {
                printf ("%-20s %-20s %-10s n", $type, $logsettings{$type}, $logcheck{$type});
            }
  

Вот в чем дело. При запуске с серией файлов (мы часто запускаем их с сотнями файлов одновременно) — первый вывод выглядит нормально:

 Found Audit GPO: Default Domain Policy
        GPO Audit Settings - Default Domain Policy:
Audit Value:         Current Setting:     Status:
AuditAccountLogon    Success, Failure     Good
AuditLogonEvents     Success, Failure     Good
AuditProcessTracking Failure              FAIL
AuditSystemEvents    Success, Failure     Good
AuditDSAccess        Failure              FAIL
AuditPolicyChange    Success, Failure     Good
AuditAccountManage   Success, Failure     Good
AuditPrivilegeUse    Failure              FAIL
AuditObjectAccess    Failure              FAIL
  

Но во всех последующих таблицах есть одна глупая строка с ошибкой-:

 Found Audit GPO: Default Domain Policy
        GPO Audit Settings - Default Domain Policy:
Audit Value:         Current Setting:     Status:
AuditProcessTracking Failure
AuditLogonEvents     Success, Failure     Good
AuditAccountLogon    Success, Failure     Good
AuditDSAccess        Failure              FAIL
AuditSystemEvents    Failure              FAIL
AuditAccountManage   Success, Failure     Good
AuditPrivilegeUse    Success, Failure     Good
AuditObjectAccess    Failure              FAIL
AuditPolicyChange    Success, Failure     Good
  

Что здесь происходит не так? Есть какие-нибудь подсказки? Я понятия не имею, почему это происходит. Мой код здесь может быть не элегантным (и, вероятно, есть способы получше — я пользователь perl, а не монах), но обычно я могу вычислить алгоритм или проблему. Это меня совершенно сбило с толку.

Заранее спасибо, ребята!

РЕДАКТИРОВАТЬ: Добавила небольшую инструкцию debug print для печати %logcheck, поскольку она устанавливала каждое значение; там, где он не показывает статус, он не устанавливается. Это единственный элемент, который не устанавливается.

Ответ №1:

Что ж! Я нашел это —

Я не инициализировал повторно (undef) хэши перед повторением цикла while снова; это вызвало всевозможные странные, каскадные проблемы. Очистка хэшей с использованием undef в нижней части цикла решила проблему.