需要一个脚本/批处理/程序运行一个命令,当父母死亡时不会被杀死

场景

我使用Zabbix监视我的服务器,最近我想为Windows添加更多的指标。 出于安全考虑,我使用了Zabbix的用户参数function,但是它将外部命令的执行限制在3秒左右。 之后,命令被强行杀害。

我想运行一些长时间运行的命令,所以我使用了Zabbix论坛的技巧:在后台运行命令,将结果写入文件并使用Zabbix来收集它们。

在* nix下,这很容易得益于“&”运算符,但在Windows的shell中没有这种支持。 更糟糕的是,当Zabbix杀死强行杀死它用来评估命令的cmd.exe时,所有subprocess都会死掉,包括未完成的后台任务。

因此,我需要一些可以切断与子女关系的东西,这样他们就不会受到级联杀手的影响。

我试过了

  • startstart /B – 他们什么都不做,因为孩子总是与父母一起死亡
  • 在StackOverflow invis.vbs WScript.Shell.Run – 有时工作。 如果这个过程被强行杀死,而不是自己戒烟,孩子们也会死亡。
  • hstart – 与hstart类似的结果
  • At命令 – 这要求你设置一个绝对时间来运行任务,而不是一个偏移量,所以代码将是相当混乱的,由于Windows的shell脚本function有限。
  • (编辑) PsExec.exe套件中的PsExec.exe – 它使用一个服务来启动命令,所以它不受kill的影响; 然而,它打印一些横幅和日志信息到StdErr,并没有开关来禁用这个。 当我使用2>NULredirect它们时,Zabbix报告一个错误。

在尝试上述不同的组合后,我注意到,如果我从invis.vbs调用hstart ,当invis.vbsinvis.vbs ,由前者启动的命令将作为无父进程invis.vbs

但是,由于我需要redirect输出,我想运行的命令总是以cmd.exe /c ""command" "args"" >log 。 vbs也删除所有的引号,所以我必须用自定义的转义序列对命令进行编码。 最终结果大概涉及五级逃逸/引用,这几乎是不可能维持的。

任何人都知道更好的解决办法

一些要求

  • 任何bat / vbs / js / Win32二进制文件都可以接受
  • 最好不要求多层次的逃跑
  • 没有.Net(包括PowerShell),因为它没有安装

  1. 分开你的冗长的脚本应该是做自己的脚本。

  2. 使用NSSM ,将该脚本变为服务; 将其“退出”操作设置为“忽略”。

  3. 为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在后台运行。