场景
我使用 Zabbix 来监控我的服务器,最近我想为 Windows 服务器添加更多指标。出于安全原因,我使用了 Zabbix 的用户参数功能,但它会将外部命令的执行时间限制为大约 3 秒。 超过 3 秒后,命令将被强制终止。
我想运行一些长期运行的命令,所以我使用了 Zabbix 论坛中的技巧:在后台运行命令,将结果写入文件并使用 Zabbix 收集它们。
由于“&”运算符的存在,在 *nix 下这相当容易,但在 Windows 的 shell 中没有这样的支持。更糟糕的是,当 Zabbix 强制终止它cmd.exe
用于评估命令的进程时,所有子进程(包括未完成的后台任务)都会终止。
因此,我需要一些东西来切断与其子级的所有联系,以便它们不会受到级联杀戮的影响。
我尝试过的方法
start
并且start /B
- 他们什么也不做,因为孩子总是和父母一起死去- WScript.Shell.Run 如下隐身程序来自 StackOverflow - 有时有效。如果
wscript
强制终止进程而不是自行退出,子进程也会终止。 hstart
- 与 invis.vbs 的结果类似At
命令——这要求您设置任务运行的绝对时间而不是偏移量,因此由于 Windows 的 shell 脚本功能有限,代码会非常混乱。- (编辑)
PsExec.exe
来自 SysInternals 套件 - 它使用服务来启动命令,因此它不受 kill 的影响;但是,它会将一些横幅和日志信息打印到 StdErr,并且没有开关可以禁用此功能。当我使用2>NUL
重定向它们时,Zabbix 会报告错误。
尝试了上述不同组合后,我注意到如果我hstart
从调用,前者启动的命令在被杀死invis.vbs
时将作为无父进程被单独保留。invis.vbs
但是,由于我需要重定向输出,因此我想要运行的命令始终是 的形式cmd.exe /c ""command" "args"" >log
。vbs 还会删除所有引号,因此我必须使用自定义转义序列对命令进行编码。最终结果涉及大约五级转义/引号,这几乎不可能维护。
谁知道更好的解决方案?
一些要求
- 任何 bat/vbs/js/Win32 二进制文件均可接受
- 最好不要要求多层级转义
- 没有 .Net(包括 PowerShell),因为尚未安装
答案1
将冗长的脚本要执行的操作分离到其自己的脚本中。
使用国家安全监测中心,将该脚本变成服务;将其退出操作设置为忽略。
为 Zabbix 启动创建一个简短的批处理文件,其内容只有一行简短的代码来启动您在上一步中创建的服务。
在步骤 2 中,或者让脚本以退出代码 0 结束,并将 AppExit\0 操作设置为退出,这将正常指示 Windows 的服务管理器将该服务标记为已停止。
答案2
你有没有尝试过超越执行? 它与 psexec 非常相似,所以我不知道您在使用 psexec 时遇到的问题是否相同,但值得一试。
答案3
我在用着
启动“mybatch.bat”
在另一个批处理文件(例如“host.bat”)中,它运行正常。host.bat 文件可以停止,而另一个文件可以正常运行。
答案4
您是否考虑过实际上不需要 Zabbix 来监控系统?相反,您可以让它监控系统上的服务写入的文件。换句话说,编写一个服务,它可以完成您需要的所有工作并将最终结果写入文件(XML、JSON、CSV,格式无关紧要,只要您以后可以从 Zabbix 读取它)。然后,您的监控应用程序只需要解析该文件,这几乎是即时发生的。