2

I am using the following script to kill a process in CLOSE_WAIT state that listens to a certain ip and to a certain port.

FOR /F "tokens=5 delims= " %%I IN (
    'netstat -ano ^| find "127.0.0.1:5900" ^| find "CLOSE_WAIT"'
) DO (
    taskkill /PID %%I
)

The script does it's job but I am looking for a small modification.

I would like the process to be killed only if there are more than 10 connections into CLOSE_WAIT state. If let's say there are only 3 connections in CLOSE_WAIT then the process shouldn't be killed.

Chris
  • 107
  • 2
  • 8
  • Funny, I just tried your command (changing the taskill line to an `echo %%I`) on a Vista computer and I got a "Running low on memory error" from Windows. I quickly went into Process Explorer and saw that cmd.exe had multiplied itself dozens of times. I nuked that entire process tree and everything calmed down. But I wonder what happened...? Do you get multiple cmd.exe processes from that cycle? – pgr Feb 01 '15 at 22:57
  • I am using this on windows 2008 and no, I only get one cmd window that closes as soon as it checks for CLOSE_WAIT so no problems on my side, except the modification I would like to have – Chris Feb 01 '15 at 22:59
  • Upon further tests I believe the problem happens when netstat returns nothing matching those criteria. I don't have connections for 127.0.0.1:5900, and I get the problem. If I search for 10.0.0.128 (I have connections there) it works fine. By the way, don't test a criteria that doesn't return anything, unless you make sure you save your work first, as this could get complicated... and make sure you have a task manager that can kill entire Process trees (a process and everything it spawned) in just one go. – pgr Feb 01 '15 at 23:11
  • The script works fine for my needs. I only need an addition something like an IF case that should kill the process only if the script finds more than 10 connections in CLOSE_WAIT but I have no idea what would be the command for this. – Chris Feb 01 '15 at 23:16
  • I got it now. I had previously named my own script netstat.cmd. That was a silly thing to do, it was calling itself infinitely. Sorry for that confusion. – pgr Feb 01 '15 at 23:35

1 Answers1

0

Here is my attempt.

I used a few tricks from this post: https://stackoverflow.com/questions/2913231/how-do-i-increment-a-dos-variable-in-a-for-f-loop

echo off

set /a c=1
setlocal ENABLEDELAYEDEXPANSION

FOR /F "tokens=5 delims= " %%I IN (
    'netstat -ano ^| find "127.0.0.1:5900" ^| find "CLOSE_WAIT"'
) DO (
    set /a c=c+1
    set /a last=%%I
)
if %c% geq 10 (
   taskkill /PID !last!
)

endlocal

Basically, during the cycle I just increment a variable. In the end, if the count is greater than 10, I kill the task.

Limitation: this only counts lines returned by the netstat and finds, and uses the last PID counted for the taskkill. It assumes all the lines are from the same PID, but this is only true in some cases (like your case, where you search for address and port).

pgr
  • 459
  • 5
  • 16
  • I've changed to 1 and 2 connections for test purpose but doesn't seem to kill the process. – Chris Feb 01 '15 at 23:29
  • Inside the final IF try adding `echo !c!` and `echo !last!` to see what the variables are when you get there. I am not 100% sure when to use %c% or !c!, so I could have a bug there. But it worked in my tests... – pgr Feb 01 '15 at 23:38
  • (Make sure you're using my edited version of the batch file, not the first one I posted. The only difference is the criteria for the first `find`) – pgr Feb 01 '15 at 23:49
  • I think I was testing it wrong. Works fine now, going to test it for a day or two when my application gets into the specified connection state. Thank a lot for your help, @pgr. Will get back and mark the answer if everything turns to be alright. – Chris Feb 02 '15 at 00:06