perl - Perl,无法捕获返回码?
问题描述
并提前感谢您。我不是 Perl 开发人员,但是,我真的爱上了 Perl。就像 bash/unix 脚本一样,功能强大。。我想学习它作为我的脚本语言,但是,此时我没有那个时间。
我的问题是返回码。
问题描述:我使用Nagios Core进行监控。我的任务是监视远程服务器上的日志文件,当日志中存在某个语句时,拉出该行,提取文件名,然后将该文件复制回摄取端点。我正在使用用 Perl 编写的 Nagios 插件,Check_logfiles。一个非常优秀和强大的插件。我可以在 Perl 的脚本中编写钩子来对触发的事件执行任务。
这是我在 check_logfiles 配置中作为子例程调用编写的插件脚本。
$scriptpath = 'C:\Program Files (x86)\Nagios\NCPA\contrib';
$protocolsdir = 'C:\Program Files (x86)\Nagios\NCPA\protocols';
$seekfilesdir = 'C:\Program Files (x86)\Nagios\NCPA\seek';
$MACROS = {
LOGS_DIR => 'C:\APMConnect\Logs',
PP_INGESTION_EP => 'C:\APMConnect\AutoDataLoader\Scandir\ManageAPM',
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:\APMConnect\Logs\AutoLoader.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:\Windows\System32\net.exe use E: \\win.alphp031.corp.bp.com\APM_Data_Storage /USER:lp814555sv xnEDs7PaD3g /PERSISTENT:YES';
my $status = system("$map_drive 2>&1");
my $exit_code = ($status >> 8) & 0xff;
# if ( $exit_code!=0 ) {
# printf "Exit Code: $exit_code\n";
# printf "Status: $status\n";
# 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:\Users\212555427\TEMP\A';
my $target_dir = 'C:\Users\212555427\TEMP\B';
# my $sout = 'java.lang.Exception:Method failed: HTTP/1.1 504 Gateway Time-out Please check configuration details and replace or update the file : \\ALPCTS000000881\Archivedir\PROCESS_ADL\FaultData20200826144206065.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>&1");
当磁盘已经安装时,我得到了这个
C:\Program Files (x86)\Nagios\NCPA\plugins\check_logfiles-3.12\plugins-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>&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 命令?来自https://docs.microsoft.com/en-us/windows/win32/debug/system-error-codes--0-499-
ERROR_ALREADY_ASSIGNED
85 (0x55)
本地设备名称已被使用。
但在做了之后……我的 $status = system("$map_drive 2>&1"); 我的 $exit_code = ($status >> 8) & 0xff;
对于已经使用或已安装的情况,我得到“2”。
确保调用中断或退出的所有其他条件以及两个 GOOD 条件允许处理或执行。
我希望这是有道理的,请告诉我,谢谢!
解决方案
system
返回进程的退出代码,也在$?
.
$^E
返回“扩展的操作系统错误”并用于具有不同方式返回进程错误代码的操作系统。在 Windows 上,这是GetLastError的结果,它给出了系统错误代码。
在 Win32 下,$^E 总是返回由 Win32 调用“GetLastError()”报告的最后一个错误信息,它描述了 Win32 API 中的最后一个错误。大多数特定于 Win32 的代码将通过 $^E 报告错误。ANSI C 和类 Unix 调用设置为“errno”,因此大多数可移植 Perl 代码将通过 $! 报告错误。
所以你的支票应该是......
my $exit = system("$map_drive 2>&1");
my $error = $^E;
if ( $exit != 0 || $error == 85 ) {
我已重命名 $status 以避免混淆。而且我已经将 $^E 分配给了一个词法变量,因为它是一个全局变量,并且会被另一个系统调用覆盖。
推荐阅读
- python - 剥离lxml中的单个元素
- python - 在运行 jupyter 的 Google Cloud VM 中导入必要的库时遇到问题
- html - 如何使另一张幻灯片图像出现?
- flutter - 在 setState() 中调用 Provider 自定义方法导致错误:或在构建期间调用 markNeedsBuild()
- python - 如何将一个函数的结果存储到一个类中?
- list - Prolog - 识别变量的子列表
- javascript - URLSearchParams.get() 返回部分值
- c# - Xamarin ProgressBar 绑定进度
- ruby-on-rails - 仅当此类型尚不存在时才渲染 h3
- vue.js - VeeValidate - 检查已验证的输入字段以启用另一个输入