Batchfile: cmd.exe closes if variable has semicolon?

328 views Asked by At

Here is a part of my batch...

for /f "delims=" %%i in ('C:\pathto\dig.exe www.example.com @8.8.8.8 +short') do set RIP=%%i
If %RIP%==93.184.216.119 (
  ECHO - PASS >> results-file.txt
) else (
  ECHO - FAIL >> results-file.txt
)

...this works fine - except, let's say the DNS server 8.8.8.8 is unavailable or broken (so for testing replace it with a bad IP) and then, normally from the command-line dig.exe will timeout and eventually return...

;; connection timed out; no servers could be reached

...followed by a return to the command prompt. So I would expect that string to get set in %RIP% and thus FAIL would be printed to the file, but what happens instead is dig.exe runs, timeout, and then cmd.exe just closes, and nothing gets written to the file, and the rest of the batch does not continue.

Any idea where I've gone wrong?

1

There are 1 answers

0
dbenham On

There is at least one reason why the RIP variable is not set - the default FOR /F EOL value is semicolon, meaning all lines that begin with ; are ignored. You need to set EOL to something you know the line cannot begin with, or disable it entirely (tricky).

It is also possible that the error message is sent to stderr instead of stdout, and FOR /F only captures stdout. If this is happening, then you must also redirect stderr to stdout using 2>&1. The special characters must be escaped (or quoted) when in the FOR /F IN() clause.

There is an awkward syntax to disable both DELIMS and EOL that can solve your problem:

for /f delims^=^ eol^= %%i in ('C:\pathto\dig.exe www.example.com @8.8.8.8 +short 2^>^&1') do set RIP=%%i

The reason your IF fails if RIP is not set is the left side is completely empty, causing the parser to fail. You can fix this by adding quotes (or any character) to both sides. But you should also explicitly clear the RIP value before the loop, just in case a prior command previously set RIP.

set "RIP="
for /f "delims=" %%i in ('C:\pathto\dig.exe www.example.com @8.8.8.8 +short') do set RIP=%%i
If "%RIP%"=="93.184.216.119" (
  ECHO - PASS >> results-file.txt
) else (
  ECHO - FAIL >> results-file.txt
)