Perl, не может захватить коды возврата?

#perl #return-value

#perl #возвращаемое значение

Вопрос:

и заранее благодарю вас. Я не разработчик Perl, однако я действительно влюбляюсь в Perl. как и сценарии bash / unix, мощный.. Я хочу изучить его как свой язык сценариев, однако на данный момент у меня нет на это времени.

моя проблема — коды возврата.

Описание проблемы: я использую ядро Nagios для мониторинга. У меня есть задача отслеживать файлы журналов на удаленном сервере, и когда в журнале существует определенный оператор, потяните эту строку, извлеките имя файла и скопируйте этот файл обратно в конечную точку приема. Я использую плагин Nagios, написанный на Perl, Check_logfiles . Действительно отличный и мощный плагин. Я могу писать скрипты в скриптах на Perl для выполнения задач при срабатывании событий.

вот мой скрипт плагина, написанный как вызов подпрограммы в конфигурации check_logfiles .

 $scriptpath = 'C:Program Files (x86)NagiosNCPAcontrib';
$protocolsdir = 'C:Program Files (x86)NagiosNCPAprotocols';
$seekfilesdir = 'C:Program Files (x86)NagiosNCPAseek';

$MACROS = {
    LOGS_DIR => 'C:APMConnectLogs',
    PP_INGESTION_EP => 'C:APMConnectAutoDataLoaderScandirManageAPM',
    SRC_DIR => 'E:Zip File Archive'
};

#$postscript = 'custom_mail_alert.pl';
#$postscriptparams = '--sender alpcts000000881@ge.com --recpt gary.l.mills@ge.com --subject "Notification - APM Loader refeed performed" --message "$CL_SERVICEOUTPUT$" --log-file "C:APMConnectLogsAutoLoader.log" --send_if_rc_gt 1 --display-name "Aviation Preprocessor Notification"';
#$postscriptstdin = '$CL_HOSTNAME$t$CL_SERVICEDESC$t$CL_SERVICESTATEID$t$CL_SERVICEOUTPUT$n';
    
@searches = (
  {
    tag => '504 Gateway Time-Out',
    logfile => '$LOGS_DIR$AutoLoader.log',
    rotation => 'AutoLoader.log.d{1,2}',
    type => 'rotating',
    criticalpatterns => [
        '^java.lang.Exception:Method failed: HTTP/1.1 504 Gateway Time-out Please check configuration details and replace or update the file :.*'
    ],
    options => 'protocol,perfdata,script,supersmartscript',
    script => sub {
        use File::Copy;
        
        $map_drive = 'C:WindowsSystem32net.exe use E: \win.alphp031.corp.bp.comAPM_Data_Storage /USER:lp814555sv xnEDs7PaD3g /PERSISTENT:YES';
        my $status = system("$map_drive 2>amp;1");
        my $exit_code = ($status >> 8) amp; 0xff;
        
#       if ( $exit_code!=0 ) {
#           printf "Exit Code: $exit_coden";
#           printf "Status: $statusn";
#           printf 'CRITICAL - APM Data Storage NAS Share Cannot be mounted!';
#           return 2;
#       }
#       my $file_name = "BHPJanFP_2018-06-25-06-43-09.csv";
#       my $source_dir = 'C:Users212555427TEMPA';
        my $target_dir = 'C:Users212555427TEMPB';
#       my $sout = 'java.lang.Exception:Method failed: HTTP/1.1 504 Gateway Time-out Please check configuration details and replace or update the file : \ALPCTS000000881ArchivedirPROCESS_ADLFaultData20200826144206065.zip';
        
        my $_source_dir = $ENV{CHECK_LOGFILES_SRC_DIR};
        my $_target_dir = $ENV{CHECK_LOGFILES_PP_INGESTION_EP};
        my $sout = $ENV{CHECK_LOGFILES_SERVICEOUTPUT};
        my $result = rindex($sout, 'FaultData');
        my $_file_name = substr($sout, $result, length($sout));
        opendir(my $DIR, $_source_dir) || die "Can't opendir $_source_dir: $!"; 

        if( -f "$_source_dir/$_file_name" ) {
            copy ("$_source_dir\$_file_name", "$target_dir\$_file_name") || die "File Copy Failed: $!";
            if ( $? == 0 ) {
                printf 'OK - File Copy Successful!';
                printf " Copied File to Refeed APM: $_source_dir\$_file_name";
                return 0;
            } else {
                printf 'CRITICAL - File Copy Failed!';
                printf " Source dir: $_source_dir\$_file_name";
                return 2;
            }
        } else {
            printf 'CRITICAL - File Copy Failed, File CANNOT be located!';
            printf "Source dir: $_source_dir\$_file_name";
            return 2;
        }
        closedir($DIR);
    }
  }
);
  

моя проблема начинается здесь, с сопоставления диска NAS. Я не знаю, как получить и / или манипулировать кодами возврата. потому что существует условие, что накопитель NAS уже смонтирован и, следовательно, используется.
Я хочу разрешить выполнение, если это условие существует, И если оно успешно смонтировано.

 my $status = system("$map_drive 2>amp;1");
  

когда диск уже смонтирован, я получаю это

 C:Program Files (x86)NagiosNCPApluginscheck_logfiles-3.12plugins-scripts>check_logf
check_logfiles.cfg"
System error 85 has occurred.

The local device name is already in use.

CRITICAL - (1 errors in check_logfiles.protocol-2020-09-24-13-40-27) - 
Exit Code: 2
Status: 512
  

Мне нужно продолжить выполнение для этого состояния и состояния 0 или успешного монтирования.

как вы фиксируете эти коды возврата?

поэтому мне, по сути, нужно что-то вроде псевдокода…

 my $status = system("$map_drive 2>amp;1");
if ( $status != 0 || $status != rc = System error 85 has occurred ) {
   printf 'CRITICAL - APM Data Storage NAS Share Cannot be mounted!';
   return 2;  (*** 2 here is for Nagios )
  

Я нашел коды возврата в систему, я полагаю, не могу найти для net command?
из https://learn.microsoft.com/en-us/windows/win32/debug/system-error-codes—0-499 —

ОШИБКА_ALREADY_ASSIGNED

85 (0x55)

Имя локального устройства уже используется.

но после выполнения … мой $status = system («$ map_drive 2> amp; 1»); мой $ exit_code = ($status >> 8) amp; 0xff;

для условия, которое УЖЕ ИСПОЛЬЗУЕТСЯ или уже установлено, я получаю ‘2’.

чтобы гарантировать, что все остальные условия вызов прерывается или завершается, а два ХОРОШИХ условия позволяют обрабатывать или выполнять.

Я надеюсь, что это имеет смысл, пожалуйста, дайте мне знать, и спасибо!!!

Комментарии:

1. спасибо, Шверн, да, моя проблема тоже, Windows … arg! Я попытался найти текст, но безуспешно.

2. Подтвердите, что вы используете use strict; use warnings; . В противном случае добавьте их и исправьте ошибки и фатальные ошибки, которые они создают, или покажите ошибки здесь.

Ответ №1:

system возвращает код завершения процесса, также в $? .

$^E возвращает «расширенную ошибку ОС» и используется в операционных системах, которые имеют отдельные способы возврата кодов ошибок процесса. В Windows это результат GetLastError, который выдает коды системных ошибок.

В Win32 $ ^ E всегда возвращает последнюю информацию об ошибке, сообщенную вызовом Win32 «GetLastError()», который описывает последнюю ошибку из Win32 API. Большинство специфичных для Win32 кодов будут сообщать об ошибках через $ ^ E. ANSI C и Unix-подобные вызовы устанавливают «errno», и поэтому большинство переносимых Perl-кодов будут сообщать об ошибках через $! .

Итак, ваша проверка должна быть примерно такой…

 my $exit = system("$map_drive 2>amp;1");
my $error = $^E;
if ( $exit != 0 || $error == 85 ) {
  

Я переименовал $status, чтобы избежать путаницы. И я назначил $ ^ E лексической переменной, потому что она является глобальной и будет перезаписана другим системным вызовом.

Комментарии:

1. Большое спасибо, Шверн, я могу попробовать это завтра и сразу же связаться с вами. изучение нового языка всегда вызывает смущение, так много же сделано по-другому 🙂 но спасибо!!!

2. что-то не так. это не работает. выдает… Код выхода: 512, ошибка: система не может найти указанный файл. И снова… Код выхода: 512, ошибка: была предпринята попытка выполнения операции над чем-то, что не является сокетом. ВСЕ ЕЩЕ НЕ получается получить хорошие коды возврата для принятия решения.

3. @GLMills Вы напечатали $^E и получили то же $? самое, что и, 512? Не могли бы вы показать perl -v , пожалуйста?

4. Не связано с этим вопросом, но @Schwern, получили ли вы мои недавние электронные письма о Method:: Signatures и Mite?

5. привет, ребята, извините и спасибо!! была небольшая неудача, но я вернулся 🙂 — эй, ну, оказывается, то, с чем я сталкиваюсь, — это реализация общего доступа к NAS и безопасность. Они сопоставили / смонтировали диск не с сохранением, не без необходимости uid / pwd. Проблема здесь в правилах диска и безопасности. Спасибо, что показали мне, как получить ответ об ошибке Win last от Perl. теперь, чтобы правильно отобразить диск. спасибо вам всем!