我使用Zabbix监视我的服务器,最近我想为Windows添加更多的指标。 出于安全考虑,我使用了Zabbix的用户参数function,但是它将外部命令的执行限制在3秒左右。 之后,命令被强行杀害。
我想运行一些长时间运行的命令,所以我使用了Zabbix论坛的技巧:在后台运行命令,将结果写入文件并使用Zabbix来收集它们。
在* nix下,这很容易得益于“&”运算符,但在Windows的shell中没有这种支持。 更糟糕的是,当Zabbix杀死强行杀死它用来评估命令的cmd.exe时,所有subprocess都会死掉,包括未完成的后台任务。
因此,我需要一些可以切断与子女关系的东西,这样他们就不会受到级联杀手的影响。
start和start /B – 他们什么都不做,因为孩子总是与父母一起死亡 hstart – 与hstart类似的结果 At命令 – 这要求你设置一个绝对时间来运行任务,而不是一个偏移量,所以代码将是相当混乱的,由于Windows的shell脚本function有限。 PsExec.exe套件中的PsExec.exe – 它使用一个服务来启动命令,所以它不受kill的影响; 然而,它打印一些横幅和日志信息到StdErr,并没有开关来禁用这个。 当我使用2>NULredirect它们时,Zabbix报告一个错误。 在尝试上述不同的组合后,我注意到,如果我从invis.vbs调用hstart ,当invis.vbs被invis.vbs ,由前者启动的命令将作为无父进程invis.vbs 。
但是,由于我需要redirect输出,我想运行的命令总是以cmd.exe /c ""command" "args"" >log 。 vbs也删除所有的引号,所以我必须用自定义的转义序列对命令进行编码。 最终结果大概涉及五级逃逸/引用,这几乎是不可能维持的。
任何人都知道更好的解决办法
分开你的冗长的脚本应该是做自己的脚本。
使用NSSM ,将该脚本变为服务; 将其“退出”操作设置为“忽略”。
为Zabbix创build一个短batch file来启动,它的内容只是一个短行来启动你在上面创build的服务。
在步骤2中,也可以让脚本以退出代码0结束,并将AppExit \ 0操作设置为退出,这将优雅地指示Windows的服务pipe理器将服务标记为已停止。
你有没有试过BeyondExec ? 这与psexec非常相似,所以我不知道你使用psexec的问题是否适用,但值得一试。
我在用着
启动“mybatch.bat”
从另一个batch file(例如“host.bat”),它工作正常。 host.bat文件可以停止,另一个文件运行良好。
build议1:
使用PSEXEC,但尝试转义redirect字符。 我不熟悉Zabbix,所以我不确定这是否会有所帮助。
psexec.exe ...args... 2^>nul
build议2:
使用包含schtasks命令的batch file。
— schedzabbixscript.cmd —
@echo off schtasks /create /ru "NT AUTHORITY\SYSTEM" /sc once /tn zabbixtemp /tr c:\path\zabbixscript.cmd /st 23:23:59 /sd 12/31/2999 schtasks /run /tn zabbixtemp
— zabbixscript.cmd —
@echo off ...command... ...command... ...command... schtasks /delete zabbixtemp /f
如果这在一台服务器上适用于您,为了在多台服务器上执行此操作,而无需login到每台服务器,则可以将用于计划任务的帐户更改为networking帐户,并将您的zabbixscript.cmd存储在中央的位置,只需要修改它,当你需要改变的东西。
你有没有考虑过你不需要Zabbix来实际监控系统? 相反,您可以使其监视由系统上的服务写入的文件。 IOW,编写一个服务,完成你所需要的任何事情,并把最终结果写入一个文件(XML,JSON,CSV,只要你稍后可以从Zabbix中读取,格式不重要)。 那么你的监控应用程序只需要parsing出应该几乎是即时发生的文件。
如果我在监视服务器,我可能会滚动我自己的批处理或bash脚本来检查服务器状态并使用Jenkins服务器来安排这些检查作业。
Windows脚本宿主是正确的解决scheme。 如果只是开始批处理作业,将永远不会有时间被杀死。 所有你需要的是:
Set quickShell = WScript.CreateObject("WScript.Shell") myCommand = "mybatchfile.bat ""first argument"" ""second argument"" > logfile.log" quickShell.Run myCommand, 0
保存为wrapper.vbs并运行它。 它将开始批处理并立即退出,使batch file在后台运行。