0

I am writing a simple batch script to just ping a ton of IPs to see if they are online. I wrote some code and every time I run it, I get an error saying

( was unexpected at this time.

I'm not sure where I went wrong. So if somebody could just tell me what to do instead that would be great. I'm kind of new to batch so my code isn't the greatest.

::@echo off
color b
title Get Online IPs
for /L %%A IN (0,1,255) do (
    for /L %%B IN (0,1,255) do (
        for /L %%C IN (0,1,255) do (
            for /L %%D IN (0,1,255) do (
                set %%A.%%B.%%C.%%D = IP
                ping -n 1 %%A.%%B.%%C.%%D > ./iptemp.txt
                for /F "delims=" %%i in (iptemp.txt) do set "iptemp=%%i"
                if %iptemp% == "Packets: Sent = 1, Received = 0, Lost = 1 (100% loss)," (
                    echo IP offline
                    goto skip
                )
                echo %IP% >> IPlist.txt
                echo %IP% is online!
                :skip
            )
        )
    )
)
Mofi
  • 46,139
  • 17
  • 80
  • 143

2 Answers2

0
for /L %%A IN (0,1,255) do (
    for /L %%B IN (0,1,255) do (
        for /L %%C IN (0,1,255) do (
            for /L %%D IN (0,1,255) do (
             set "flag="
             for /F "delims=" %%i in ('ping -n 1 %%A.%%B.%%C.%%D') do (
              if "%%i" == "Packets: Sent = 1, Received = 0, Lost = 1 (100% loss)," set flag=Y
             )
             if defined flag (
              echo %%A.%%B.%%C.%%D offline
             ) else (
              echo %%A.%%B.%%C.%%D >> IPlist.txt
              echo %%A.%%B.%%C.%%D  is online!
             )
            )
        )
    )
)

{untested}

set %%A.%%B.%%C.%%D = IP

Will set environment variables 0.0.0.0Space .. 255.255.255.255Space to a value of "SpaceIP" Spaces are significant on both sides of the = operator in a standard set statement - and you can't simply reverse the syntax and expect cmd to work out what you mean.

  for /F "delims=" %%i in (iptemp.txt) do set "iptemp=%%i"

will set the value of iptemp to the contents of the last line of the file. It's unlikely to match the string you have chosen in the later test.

And you can't use a label within a "block statement" (parenthesised series of statements)

Furthermore, as is explained in thousands of SO responses, in order to access the run-time value of a variable within a block, you need to invoke delayedexpansion mode and use !var!. (There are other ways - this is the simplest). %var% is always the value of the variable when the block statement was encountered

An this is the source of your error report - actually "( was NOT expected at this time". As iptemp is undefined when the block is encountered (and that block is the for /L %%A ... block), cmd interprets this line as

if == "Packets: Sent = 1, Received = 0, Lost = 1 (100% loss)," (

and can make no sense of it.

Your 'IP offline' report would say precisely that - 'IP offline' - not the IP address.

The revised (but untested) code uses flag as a sack of potatoes and initialises it to empty - the enclosing quotes ensure that any trailing spaces are not included in the value assigned to flag

The for/f delivers the entirity of each line of the ping output to %%i in turn, and then each line (now in %%i) is compared to your magic string (note that both sides need to be quoted) and flag is set to something - anything will do if the magic string matches any output line.

When the for/f finishes, the current value of flag is interpreted (note that if defined works on the current value, not the initial value) and one or other of the reports is generated.

Magoo
  • 77,302
  • 8
  • 62
  • 84
0

I don't understand why you want to ping the entire IPv4 address range, i.e. ping all IPv4 addresses of the world. Do you know that you try to ping 4 294 967 296 addresses?

The line set %%A.%%B.%%C.%%D = IP is completely wrong. The name of the variable and the string value to assign to the variable are on wrong side of the equal sign. And take at look on Why is no string output with 'echo %var%' after using 'set var = text' on command line? for an explanation why there should be no spaces around the equal sign.

Delayed environment variable expansion is needed whenever a variable is defined or modified within a command block starting with ( and ending with matching ) and the value of the variable is referenced in same command block. Run in a command prompt window set /? and read all output help pages for details about delayed expansion as used in the code below.

Windows command processor does not support labels within a FOR loop. The solution here is using IF with ELSE.

The IF condition could be never true as compared is a string with no double quotes with a string with double quotes. The surrounding double quotes are needed here for the string comparison, but they are not removed by command IF from the compared strings.

The IF condition for string comparison is also the reason for the syntax error because environment variable iptemp is not defined above first FOR and is therefore undefined on parsing the command block. This results in replacing %iptemp% already before most outer FOR being first time executed by nothing resulting in the line

if  == "Packets: Sent = 1, Received = 0, Lost = 1 (100 loss)," (

And this line is of course completely wrong. Note: Single percent sign is also removed.

The percent sign in the string to compare must be escaped with one more percent sign to be interpreted as literal character and not as beginning of a variable reference.

In code below in last ECHO line the exclamation mark must be escaped with ^^ to be interpreted as literal character because of delayed expansion being enabled which changes meaning of ! from a simple literal character to delimiter of a variable name whose value should be referenced without expansion on parsing the command block.

@echo off
setlocal EnableDelayedExpansion
color b
title Get Online IPs
set "ListFile=IPlist.txt"
if exist "%ListFile%" del "%ListFile%"
for /L %%A in (0,1,255) do (
    for /L %%B in (0,1,255) do (
        for /L %%C in (0,1,255) do (
            for /L %%D in (0,1,255) do (
                set "IP=%%A.%%B.%%C.%%D"
                for /F "delims=" %%i in ('%SystemRoot%\System32\ping.exe -n 1 !IP!') do set "iptemp=%%i"
                if "!iptemp!" == "Packets: Sent = 1, Received = 0, Lost = 1 (100%% loss)," (
                    echo !IP! is offline.
                ) else (
                    echo !IP! is online^^!>>"%ListFile%"
                )
            )
        )
    )
)
endlocal

On my German Windows the string comparison is never true and therefore all IPs are "online" which of course is wrong.

Much better would be using exit code of console application PING which is 0 on successful pinging and 1 on error. The exit code of previously executed command or console application can be evaluated with if errorlevel X respectively if not errorlevel X depending on checking exit code (errorlevel) for greater or equal X or lower than X.

@echo off
setlocal EnableDelayedExpansion
color b
title Get Online IPs
set "ListFile=IPlist.txt"
if exist "%ListFile%" del "%ListFile%"
for /L %%A in (0,1,255) do (
    for /L %%B in (0,1,255) do (
        for /L %%C in (0,1,255) do (
            for /L %%D in (0,1,255) do (
                set "IP=%%A.%%B.%%C.%%D"
                %SystemRoot%\System32\ping.exe -n 1 !IP! >nul
                if errorlevel 1 (
                    echo !IP! is offline.
                ) else (
                    echo !IP! is online^^!>>"%ListFile%"
                )
            )
        )
    )
)
endlocal

For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.

  • color /?
  • del /?
  • echo /?
  • endlocal /?
  • for /?
  • if /?
  • ping /?
  • set /?
  • setlocal /?
  • title /?

Read also the Microsoft articles:

Community
  • 1
  • 1
Mofi
  • 46,139
  • 17
  • 80
  • 143