1.

Solve : Trouble with Incrementing a Variable?

Answer»

I am attempting to WRITE a program that will ping a list of machines on our network and INCREMENT a variable based on whether or not a reply is received. The program reads the IP's from a host file and should ping each machine X amount of times. Then the variables for successes and failures will be compared (this part isn't written yet) and run some commands. However, I can not seem to get the counterOK and counterFailed variables to increment. I have been working on this for two days and I think I just need another set of eyes to point me in the right direction. This is the what I have so far.



@ECHO off
title Network Monitor
REM set variables for batch file
set NrOfPings=3
set counterOK=0
set counterFailed=0
set dPath=c:\users\%username%\desktop\monitor\
set hostfile=%dPath%myhosts.txt
set pingLog=%dPath%ping.txt

if EXIST del %pingLog%

REM echo %hostfile%
REM echo %pingLog%
REM echo %counterOK%
REM echo %counterFailed%
REM pause


REM create a loop to go through the ip addresses in the host file
for /f %%z in (%hostfile%) do (
set counterOK=0
set counterFailed=0
rem create a loop to ping each machine 10 times
for /l %%i in (1, 1, %NrOfPings%) do (
echo this is attempt %%i for IP %%z


ping -n 1 %%z > %pingLog%
find "Reply from" %pingLog%
IF ERRORLEVEL 0 set /a counterOK=%counterOK%+1
IF NOT ERRORLEVEL 0 set /a counterFailed=%counterFailed%+1
echo good:%counterOK% bad:%counterFailed%
echo.
PAUSE
ECHO.
)
)

del %pingLog%
pause

exit





Any help would be greatly appreciated.
not sure how to count++ increment in batch either, so I will be keeping an eye on this thread for how. Its easy in other languages. Just never done it in batch to be able to show how.This is an oldie but goodie. I knew when I saw the thread title what the problem was. Everybody who reaches the level in batch scripting of using loops seems to wonder "Why don't my variables change value in a loop?" The answer is to do with the way that the command interpreter expands variables before running a script. Variables which are set (and read) inside a loop or other parenthetical structure such as a FOR loop or extended IF structure or a && or || block will NOT change unless you use DELAYED EXPANSION.

1. Put this command before the loop. At the top of the batch file straight under the @echo off LINE is as good as anywhere else.

setlocal enabledelayed expansion

2. The variables inside the loop don't have percent signs before and after - they use exclamation MARKS instead.

3. There are a zillion web pages about it... take your pick...

http://www.google.com/search?source=ig&hl=en&rlz=&q=delayed+expansion&aq=0&aqi=g3g-v4g-m3&aql=&oq=delayed+expa





Code: [Select]setlocal enabledelayedexpansion
REM create a loop to go through the ip addresses in the host file
for /f %%z in (%hostfile%) do (
set counterOK=0
set counterFailed=0
rem create a loop to ping each machine 10 times
for /l %%i in (1, 1, %NrOfPings%) do (
echo this is attempt %%i for IP %%z
ping -n 1 %%z > %pingLog%
find "Reply from" %pingLog%
IF !errorlevel! equ 0 (
set /a counterOK+=1
) else (
set /a counterFailed+=1
)
echo good:!counterOK! bad:!counterFailed!
echo.
PAUSE
ECHO.
)
)Humm. The batch command

setlocal enabledelayed expansion

is a Windows Batch command, not an MS-DOS batch comand. Won't work with MS-DOS 6.x or PC-DOS 7.


I don't believe that MS-DOS has a counter batch command native to it.

Years ago in the 80's & 90's I used an MS-DOS executable that I called from the batch file when I needed a counter. I can't recall the exact name but when I'm home next week I'll see if I can dig it out.Quote from: aoresteen on June 22, 2011, 03:10:59 PM

Humm. The batch command

setlocal enabledelayed expansion

is a Windows Batch command, not an MS-DOS batch comand.

Yes, we know! Your point is?

It's not just Windows - the OP's code is clearly Windows NT family batch scripting language.

PC-DOS 7 has Rexx.





Better to pipe the output of Ping into FIND and look for the text "TTL", because "Reply from" in the output of PING does not always indicate a positive response. You may receive a message from a router such as: Reply from 192.168.1.254: Destination Net Unreachable.

Also no need for log.txt.

Code: [Select]setlocal enabledelayedexpansion
REM create a loop to go through the ip addresses in the host file
for /f %%z in (%hostfile%) do (
set counterOK=0
set counterFailed=0
rem create a loop to ping each machine 10 times
for /l %%i in (1, 1, %NrOfPings%) do (
echo this is attempt %%i for IP %%z
ping -n 1 %%z | find "TTL=" > nul
IF !errorlevel! equ 0 (
set /a counterOK+=1
) else (
set /a counterFailed+=1
)
echo good:!counterOK! bad:!counterFailed!
echo.
PAUSE
ECHO.
)
)I made the changes suggested in the replies but the variables still refuse to increment. I should have mentioned this in the beginning but this batch file will be running in a Windows 7/Server 2008 environment. Here is what I have changed the code to


@echo off
setlocal enabledelayedexpansion
title Network Monitor

REM set variables for batch file
set NrOfPings=3
set counterOK=0
set counterFailed=0
set dPath=c:\users\%username%\desktop\monitor\
set hostfile=%dPath%myhosts.txt

REM create a loop to go through the ip addresses in the host file
for /f %%z in (%hostfile%) do (
set counterOK=0
set counterFailed=0
rem create a loop to ping each machine 10 times
for /l %%i in (1, 1, %NrOfPings%) do (
echo this is attempt %%i for IP %%z


ping -n 1 %%z | find "TTL" > nul
IF !ERRORLEVEL! equ 0 (
set /a counterOK+=1
) else (
set /a counterFailed+=1
)
echo good:%counterOK% bad:%counterFailed%
echo.
PAUSE
ECHO.
)
)

pause

exit

Code: [Select]echo good:%counterOK% bad:%counterFailed%
I told you already you need to use exclamation marks, not percent signs, with delayed expansion in loops.
sorry I missed that line. It works now!

Thanks!!Quote from: Salmon Trout on June 22, 2011, 03:43:43 PM
Yes, we know! Your point is?

It's not just Windows - the OP's code is clearly Windows NT family batch scripting language.

PC-DOS 7 has Rexx.

Sorry Salmon. I don't see where in the OP posting he says he's using Windows:

"..I am attempting to write a program that will ping a list of machines on our network and increment a variable based on whether or not a reply is received. The program reads the IP's from a host file and should ping each machine X amount of times. Then the variables for successes and failures will be compared (this part isn't written yet) and run some commands. However, I can not seem to get the counterOK and counterFailed variables to increment. I have been working on this for two days and I think I just need another set of eyes to point me in the right direction. This is the what I have so far."

I guess since I'm a DOS guy I didn't consider Windows batch code.

My main DOS is PC DOS 7 and I do use REXX on occasion but I never assume every DOS user has REXX available to them. Glad he's sorted it out.

Quote from: aoresteen on June 27, 2011, 08:42:27 PM
Sorry Salmon. I don't see where in the OP posting he says he's using Windows:

In his code the use of for /f and for /l (absent in MS-DOS and Win 9x) confirm that he is writing for cmd.exe, the NT family command interpreter. In his revised code, the second line, where he invokes delayed variable expansion, identifies the environment as a Windows 2000 or later version of cmd.exe.





Discussion

No Comment Found