batch-filefindstrtaskkilltasklist

Ending specific task/process with batch script if it's found in tasklist


For context, I found this among XAMPP batch files:

@echo off 
SetLocal EnableDelayedExpansion
set "PID_LIST="

for /f "tokens=2" %%V in ('tasklist.exe ^| findstr /i "%1" 2^>NUL') do @set "PID_LIST=!PID_LIST! /PID %%V"

if defined PID_LIST (
  taskkill.exe /F %PID_LIST%
) else (
  echo Process %1 not running
)

SetLocal DisableDelayedExpansion
exit

I wish to write a single script to end all tasks related to my webserver. I have a basic understanding of batch, so I have been able to interpret most of what this script does:

  1. Delayed expansion is needed for the for loop
  2. The for loop gets the second token (PID) from tasklist and saves it into a variable, where the task is given by paramater 1.
  3. If the task is found it is ended with taskkill

Based on this I came so far:

@echo off
cd /D %~dp0
for /f "tokens=2" %%V in ('tasklist.exe ^| findstr /i "httpd.exe" 2^>NUL') do taskkill.exe /pid /f %%V
for /f "tokens=2" %%V in ('tasklist.exe ^| findstr /i "mysql" 2^>NUL') do taskkill.exe /pid /f %%V
:: etc

But I would ideally collapse this into one for loop. How could I add or logic to the findstr expression?

I also have a few questions, which I can't find quick answers to anywhere. Can anyone answer these in the comments?

  1. In my script, do I need to EnableDelayedExpansion?
  2. What is the purpose of set "PID_LIST=", leaving the variable undefined?
  3. I don't fully understand the command pipe findstr: what is the meaning of 2^>NUL, and why does > need to be careted?
  4. How does the set command append to the variable with !VARIABLE!?

Solution

    1. Yes in the first script; no in the second.
    2. To ensure that PID_LIST is undefined, in case it has been left defined from some prior operation.
    3. 2>nul redirects error messages from the command to nowhere instead of the console. The carets before the redirectors are escape characters, telling the parser that the redirector is part of the immediately-prior command, not of the for.
    4. When delayedexpansion is in effect, !var! retrieves the current value of the variable, whereas %var% is replaced by the value of the variable at the time that the code block (parenthesised sequence of lines) was parsed.

    Tips:
    Always use a setlocal flavour to avoid environment clutter. If setlocal is used (usually directly after the @echo off line) then when the batch ends, any changes to the environment are undone, so successive batches will not accumulate changes and the environment state whenever a batch is started will always be the same.

    See Stephan's DELAYEDEXPANSION link

    To accomplish the or you seek, use

    findstr /i /c:"httpd.exe" /c:"mysql"
    

    (and you can add any number of /c:"literalstring" elements.

    findstr can also be supplied with

    findstr /i "httpd.exe mysql"
    

    in this case; the space in the literal meaning string or string. If you want to target a string that contains a space, use the /c:"this string" /c:"that string" syntax.

    See findstr /? from the prompt for more documentation - or see thousands of examples on SO