Files
autoreg-skills-max/skills/treg-to-farm/scripts/kill_farm_loops.py

40 lines
1.8 KiB
Python

"""Kill farm loop processes on Windows: wrappers first (tree kill), verify to zero.
Usage: python kill_farm_loops.py "regex_pattern" [max_rounds]
Pattern uses bracket-trick against self-match, e.g. 'treg_farm_v[3]|v3_loo[p]'.
Python subprocess instead of powershell one-liners: git-bash eats $_.
"""
import subprocess, sys, time, os
PATTERN = sys.argv[1] if len(sys.argv) > 1 else r'treg_farm_v[34]|v[34]_loo[p]'
MAX_ROUNDS = int(sys.argv[2]) if len(sys.argv) > 2 else 6
def ps(cmd):
return subprocess.run(['powershell', '-NoProfile', '-Command', cmd],
capture_output=True, text=True).stdout
def find(pattern):
out = ps(r'''Get-CimInstance Win32_Process | Where-Object {$_.CommandLine -match '%s'} | ForEach-Object {"$($_.ProcessId)|$($_.Name)|$($_.CommandLine)"}''' % pattern)
rows = []
for l in out.splitlines():
parts = l.split('|', 2)
if len(parts) >= 2 and parts[0].strip().isdigit():
rows.append((int(parts[0].strip()), parts[1].strip(), parts[2] if len(parts) > 2 else ''))
me = os.getpid()
return [r for r in rows if r[0] != me and 'kill_farm_loops' not in r[2] and 'Get-CimInstance' not in r[2]]
for rnd in range(MAX_ROUNDS):
rows = find(PATTERN)
if not rows:
print('ALL DEAD'); sys.exit(0)
print(f'round {rnd}:', [(p, n) for p, n, _ in rows])
# wrappers (bash/sh running the loop script) FIRST — otherwise they respawn python children
wrappers = [r for r in rows if '_loop' in r[2] or r[1].lower() in ('bash.exe', 'sh.exe')]
others = [r for r in rows if r not in wrappers]
for p, n, c in wrappers + others:
subprocess.run(['taskkill', '/F', '/T', '/PID', str(p)], capture_output=True)
time.sleep(3)
print('STILL ALIVE after %d rounds — manual check' % MAX_ROUNDS)
for p, n, c in find(PATTERN):
print(p, n, c[:120])
sys.exit(1)