Instead of checking if the ping
output contains "Reply from", it's better to search for "TTL=":
ping -n 1 10.0.0.1| findstr "TTL="
as pointed in this answer. Searching for "TTL=" after a ping will be more reliable than searching for "Reply from". There are some ping error messages with "Reply from". In some cases you can get a reply from another machine stating that the machine you're looking for is not reachable for example. You'll then have a "Reply from" in the failed ping output.
If you want to use the ping with the findstr
and its errorlevel in a for loop you cannot not use goto
to jump to a label. The goto
will destroy your loop context. You can see goto
as a command that tells the parser to abandon the command it was processing/executing (the FOR
loop) and start at the label you gave as argument. It will just forget about the loop.
I will assume your labels are arranged this way:
:PASS
rem some commands in case the ping succeeded
<commands_succes>
goto :BOTH
:FAIL
rem some code in case the ping failed
<commands_fail>
:BOTH
rem code that has to be executed in both cases after code for individual case (if any)
<commands_after>
Your loop can then take these different forms:
using IF ERRORLEVEL 1 ( ... ) ELSE ( )
and move all code from the :FAIL
label to the if-branch and all code from the :PASS
label to the else-branch. The code from the :BOTH
label (if any) will come under the whole if-block
for /f "tokens=2 delims=:" %%g in ('netsh interface ip show address ^| findstr /C:"Default Gateway"') do (
ping %%g | findstr "TTL=">NUL
IF ERRORLEVEL 1 (
rem Here comes code in case the ping failed (code for :FAIL label)
<commands_fail>
) ELSE (
rem Here comes code in case the ping succeeded (code for :PASS label)
<commands_succes>
)
rem code that has to be executed in both cases after code for individual case (if any)
<commands_after>
)
use function calls with the call
command instead of goto
. If the call
command is used with labels it does the same as the goto
except that the parser will remember its state (command it was executing) and will come back to it after the execution of the label is exited. so it will execute commands from the label untill an explicit exit
, goto :EOF
or end of file is encountered.
for /f "tokens=2 delims=:" %%g in ('netsh interface ip show address ^| findstr /C:"Default Gateway"') do (
ping %%g | findstr "TTL=" > NUL
IF ERRORLEVEL 1 (
rem ping failed
call :FAIL
) ELSE (
rem ping succeeded
call :PASS
)
)
exit /b 0
:PASS
rem some commands in case the ping succeeded
<commands_succes>
goto :BOTH
:FAIL
rem some code in case the ping failed
<commands_fail>
:BOTH
rem code that has to be executed in both cases after code for individual case (if any)
<commands_after>
exit /b 0
Both cases should work for you. You'll just have to copy-paste the code corresponding to the <commands_fail>
, <commands_success>
and <commands_after>
on the right places. If you don't have anything in <commands_after>
you can just leave it blank.
EDIT: Thanks to @Josefz who noticed a little mistake I missed in the command you use in the FOR
loops to get the IP address of the default gateway:
netsh interface ip show address | findstr "Default Gateway"
The issue is that findstr
uses whitespace as delimiter for its regular expressions (whitespace in findstr
= |
in grep = OR
operator). So what it will be looking for in the case above is Default
or Gateway
and will not only give you the default gateway but also the gateway metric which isn't even an IP address. Use the /C
switch of findstr
to make it look for litteral string Default Gateway
:
netsh interface ip show address | findstr /C:"Default Gateway"
I've corrected it in the code samples above as well.
Good luck!
PS: In both cases you can use conditional execution instead of checking the errorlevel. Follow the link for more info but be sure to read the note also!