Vraag Een script / batch / programma nodig dat een opdracht uitvoert die niet wordt gedood als de ouder wordt vermoord


Het scenario

Ik gebruik Zabbix om mijn servers te bewaken en onlangs wilde ik nog wat statistieken toevoegen voor de Windows-versie. Om veiligheidsredenen gebruikte ik Zabbix's Gebruikersparameter functie, maar het beperkt de uitvoering van externe opdrachten tot ongeveer 3 seconden. Daarna wordt het bevel met geweld gedood.

Ik wil wat lange-termijnopdrachten uitvoeren, dus ik gebruikte de truc van het Zabbix-forum: voer de opdracht op de achtergrond uit, schrijf de resultaten naar een bestand en gebruik Zabbix om ze te verzamelen.

Dit is vrij eenvoudig onder * nix dankzij de "&" -operator, maar er is geen dergelijke ondersteuning in de shell van Windows. Tot overmaat van ramp, als Zabbix met geweld de doden doodt cmd.exe het evalueerde de commando's, alle onderliggende processen gingen dood, inclusief de onafgemaakte achtergrondtaken.

Dus ik heb iets nodig dat alle banden met zijn kinderen kan verbreken, zodat ze niet zullen worden beïnvloed in de trapsgewijze moord.

Wat ik heb geprobeerd

  • start en start /B - Ze doen niets omdat het kind altijd met de ouder doodgaat
  • WScript.Shell.Run als in invis.vbs van StackOverflow - Soms werk. Als het wscript proces wordt met geweld gedood in plaats van alleen te stoppen, de kinderen zullen ook sterven.
  • hstart - vergelijkbare resultaten als invis.vbs
  • At command - Dit vereist dat je een absolutietijd instelt om de taak uit te voeren in plaats van een offset, dus de code zou behoorlijk rommelig zijn vanwege de beperkte shell scripting mogelijkheid van Windows.
  • (Bewerk)  PsExec.exe van de SysInternals suite - Het gebruikt een service om het commando te starten, dus het wordt niet beïnvloed door de kill; het drukt echter wat banner- en loginformatie af naar StdErr en er is geen switch om dit uit te schakelen. Wanneer ik gebruik 2>NUL om ze om te leiden, meldt Zabbix een fout.

Nadat ik het bovenstaande in verschillende combinaties had geprobeerd, merkte ik dat ik belde hstart van invis.vbs, de opdracht die door de eerste is gestart, wordt alleen gelaten als een ouderloos proces wanneer invis.vbs is vermoord.

Omdat ik echter de uitvoer moet omleiden, is de opdracht die ik wil uitvoeren altijd in de vorm van cmd.exe /c ""command" "args"" >log. De vbs verwijdert ook alle aanhalingstekens, dus ik moet de opdracht coderen met zelf gedefinieerde escape-sequences. Het eindresultaat omvat ongeveer vijf niveaus van ontsnapping / quotering, wat bijna onmogelijk te handhaven is.

Iedereen kent betere oplossingen?

Sommige vereisten

  • Elk bat / vbs / js / Win32 binair bestand is acceptabel
  • Het is beter om niet meerdere niveaus van ontsnapping te vereisen
  • Geen .Net (inclusief PowerShell) omdat het niet is geïnstalleerd

6
2018-01-25 03:28


oorsprong


Kun je een geplande Windows-taak niet gebruiken om het programma uit te voeren? - adaptr
Zie mijn opmerkingen over de at commando. Voor het gebruik van Geplande taken moet ik zowel de planning als de exacte opdracht definiëren. Omdat ik de parameters van de metriek regelmatig moet wijzigen (vooral tijdens netwerkproblemen), moet ik me aanmelden bij elke server en de taken handmatig wijzigen. Groepsbeleid kan tot 1 uur duren om te implementeren, dus dat is ook geen optie. - billc.cn


antwoorden:


  1. Scheid wat je lange script eigenlijk hoort te doen in zijn eigen script.

  2. Gebruik makend van NSSM, maak van dat script een dienst; stel de Exit-actie in op Negeren.

  3. Maak een kort batchbestand voor Zabbix om te starten, de inhoud ervan is slechts één korte regel om de service te starten die u in de bovenstaande stap hebt gemaakt.

Laat in stap 2 het script eindigen met exitcode 0 en stel de actie AppExit \ 0 in op Exit, waarmee Windows 'Service Manager sierlijk wordt geïnstrueerd om de service als gestopt te markeren.


1
2018-01-13 18:49





Heb je geprobeerd BeyondExec? Het lijkt erg veel op psexec, dus ik weet niet of hetzelfde probleem dat je hebt met psexec van toepassing zou zijn, maar het is het proberen waard.


1
2018-01-25 22:13





ik gebruik

start "mybatch.bat"

vanuit een ander batchbestand (bijvoorbeeld "host.bat") en het werkt prima. Het host.bat-bestand kan worden gestopt en het andere bestand wordt prima uitgevoerd.


0
2018-01-25 17:35



Ik probeerde dit gewoon en ik besefte dat dit het eerste was dat ik probeerde en verwierp. De bat-bestanden worden inderdaad niet gedood, maar ze brengen twee andere problemen: 1) ze genereren zichtbare vensters en 2) de start opdracht zorgt er in feite voor dat de ouder wacht totdat de onderliggende batchbestanden zijn voltooid voordat deze wordt afgesloten. Dit zorgt ervoor dat het hele ding de time-out van 3 seconden overschrijdt en ertoe leidt dat Zabbix deze statistiek verhoogt en verhelpt en uitschakelt. - billc.cn


Suggestie 1:

Gebruik PSEXEC, maar probeer te ontsnappen aan het omleidingskarakter. Ik ken Zabbix niet, dus ik weet niet zeker of dit wel helpt.

psexec.exe ...args... 2^>nul

Suggestie 2:

Gebruik een batchbestand met schtasks-opdrachten.

--- 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

Als dit voor u op één server werkt, om dit op meerdere servers te doen zonder u bij elke server aan te melden, kunt u het account dat voor de geplande taak wordt gebruikt, wijzigen in een netwerkaccount en uw zabbixscript.cmd opslaan in een centrale locatie en bewerk deze gewoon wanneer u iets moet veranderen.


0
2018-04-12 13:53





Bent u van mening dat u Zabbix niet nodig hebt om de systemen daadwerkelijk te bewaken? In plaats daarvan kunt u ervoor zorgen dat het een bestand bewaakt waarnaar een service op het systeem is geschreven. IOW, schrijf een service die alles doet wat je nodig hebt en de eindresultaten naar een bestand schrijft (XML, JSON, CSV, het formaat doet er niet toe zolang je het later vanuit Zabbix kunt lezen). Dan zou je monitoring-app alleen dat bestand moeten analyseren, wat bijna ogenblikkelijk zou moeten gebeuren.


0
2017-08-26 17:46





Als ik servers zou monitoren, zou ik waarschijnlijk mijn eigen batch- of bash-scripts gebruiken om de serverstatus te controleren en die controletaken in te plannen met een Jenkins-server.


0
2017-09-12 21:46





Windows Script Host is de juiste oplossing. Als het alleen de batchtaak start, zal deze nooit hebben tijd vermoord worden. Alles wat je nodig hebt is:

Set quickShell = WScript.CreateObject("WScript.Shell")
myCommand = "mybatchfile.bat ""first argument"" ""second argument"" > logfile.log"
quickShell.Run myCommand, 0

Bewaar dat als wrapper.vbs en voer het uit. Het start de batch en sluit onmiddellijk af, waardoor het batchbestand op de achtergrond wordt uitgevoerd.


0
2017-09-18 09:43