#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. теперь, чтобы правильно отобразить диск. спасибо вам всем!