需要一个脚本/批处理/程序来运行一个在父进程被杀死时不会被杀死的命令

bil*_*.cn 6 scripting windows

场景

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

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

由于“&”运算符,这在 *nix 下相当容易,但 Windows 的 shell 中没有这样的支持。更糟糕的是,当 Zabbix kills 强行杀死cmd.exe它用来评估命令的程序时,所有子进程都会死亡,包括未完成的后台任务。

因此,我需要一些可以切断与其孩子的所有联系的东西,这样他们就不会在级联杀戮中受到影响。

我试过的

  • start并且start /B- 他们什么都不做,因为孩子总是和父母一起死去
  • WScript.Shell.Run as invis.vbs from StackOverflow - 有时工作。如果wscript进程被强行终止而不是自行退出,那么孩子们也会死亡。
  • hstart - 与 invis.vbs 类似的结果
  • At 命令 - 这需要您为任务设置一个绝对时间,而不是偏移量,因此由于 Windows 的 shell 脚本功能有限,代码会非常混乱。
  • (编辑) PsExec.exe来自 SysInternals 套件 - 它使用服务来启动命令,因此它不受杀死的影响;但是,它会向 StdErr 打印一些横幅和日志信息,并且没有禁用此功能的开关。当我2>NUL用来重定向它们时,Zabbix 报告错误。

在以不同的组合尝试上述操作后,我注意到如果我调用hstartfrom invis.vbs,前者启动的命令在invis.vbs被杀死时将作为无父进程单独存在。

但是,由于我需要重定向输出,因此我要运行的命令始终采用cmd.exe /c ""command" "args"" >log. vbs 还删除了所有引号,因此我必须使用自定义转义序列对命令进行编码。最终结果涉及大约五个级别的转义/引用,这几乎不可能维持。

有人知道更好的解决方案吗?

一些要求

  • 任何 bat/vbs/js/Win32 二进制文件都是可以接受的
  • 最好不需要多级转义
  • 没有 .Net(包括 PowerShell),因为它没有安装

pep*_*uan 1

  1. 将冗长的脚本应该执行的操作分离到自己的脚本中。

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

  3. 创建一个简短的批处理文件以供 Zabbix 启动,其内容只有一小行,用于启动您在上一步中创建的服务。

或者,在步骤 2 中,让脚本以退出代码 0 结束,并将 AppExit\0 操作设置为退出,这将优雅地指示 Windows 服务管理器将服务标记为已停止。