0

I need to read the contents of a PID file into a variable to then kill that process. The file is named "httpd.pid" and has this content:

40228

(It has a newline at the end.)

I learned to read the contents of that file into a variable in a CMD script file like this:

if exist apache\logs\httpd.pid (
    type apache\logs\httpd.pid
    set /p pid=<apache\logs\httpd.pid
    echo PID: %pid%
    taskkill /pid %pid%
)

The script contains extra code to debug it. Because it doesn't work. Here's what happens:

When I run the script in a new console window, it prints this:

40228
PID:
FEHLER: Ungültige Syntax. Erwarteter Wert für "/pid".
Geben Sie "TASKKILL /?" ein, um die Syntax anzuzeigen.

Notice the PID 40228 in the first line, but the empty value in the second line. I can repeat this as often as I want, the variable pid will always be empty, although the file is not!

Only when I keep the console window open and run the script twice, from the second time on, it prints this:

40228
PID: 40228
FEHLER: Der Prozess "40228" wurde nicht gefunden.

It is expected that the process was not found. But at least now it actually had the PID from the file.

Even more interesting, when I keep the console window open and call the script more often while the process existed, is started again and then writes its new PID into the file, this script will still read the PID from the last time I called it! It has a spooky memory somewhere in it that I can't explain. It always needs a second time to read current data from the file. The first time, it will read nothing at all or the file contents from the last script invocation time.

All of this only affects the pipe method. The type command always prints the current and correct file contents. The alternative reading method with the for command has the exact same behaviour:

for /f %%G in (apache\logs\httpd.pid) do set pid=%%G

What's happening here?

The computer is running Windows 10 (1709), 64 bit.

ygoe
  • 18,655
  • 23
  • 113
  • 210
  • 2
    In your given example, you are attempting to use a variable Set within a Code Block -Code between `()`. To do so, you need to `Setlocal EnableDelayedExpansion` prior to the code block and expand the variable using `!` instead of `%`, So: `echo PID: !pid!` and: `taskkill /pid !pid!` – T3RR0R Jul 11 '20 at 19:28
  • 1
    There is no _spooky memory_ involved here. When a code block is parsed, variables expanded using 'normal' `%` expansion are read with the value they had **prior** to the execution of that code block – T3RR0R Jul 11 '20 at 19:34
  • Thanks for the explanation. Strange syntax. I decided to break up the block in two and evaluate `%pid%` in the second one. That also allows me to check for an empty file. That works now. – ygoe Jul 11 '20 at 20:03

0 Answers0