N Sword
N Sword

Reputation: 1

'for' loop variable not releasing on loop iterations

Been wrecking my brain all night trying to figure out why this isn't working, but one of my variables isn't releasing on the next iteration of my loop and I can't figure out why... The first pass of the loop seems to work fine, but the next iteration, the first variable gets locked and the script connects to the system that's already been configured.

I've been staring at this for a while now and no matter how I approach it, it still behaves badly. :/ The purpose is to read a text-string of a given file, and use it to modify (via Find and Replace (fnr.exe)) another file with several instances of the required data. I didn't have alot of luck with 'findstr' replacing so many instances of the text required so I went with a tool I've used before that seemed to work really well in it's previous scripting application...

Truth be told, I find myself stumbling with even the most basic code a lot of times, so any kind soul willing to impart some wisdom/assistance would be greatly appreciated!

Thanks in advance...

@ECHO ON
setlocal enabledelayedexpansion

> "%~dp0report.log" ECHO Batch Script executed on %DATE% at %TIME%

rem read computer list line by line and do
FOR /F %%A in (%~dp0workstations.txt) do (
    SET lwn=
    SET WKSTN=%%A

    rem connect to workstation and read lwn.txt file
    pushd "\\%WKSTN%\c$\"

    IF ERRORLEVEL 0 (
        FOR /F %%I in (\\%wkstn%\c$\support\lwn.txt) DO (
            SET LWN=%%I

            %~dp0fnr.exe --cl --dir "\\%WKSTN%\c$\support\folder\config" --fileMask "file.xml" --find "21XXXX" --replace "%%I"

            IF ERRORLEVEL 0 ECHO Station %LWN%,Workstation %WKSTN%,Completed Successfully >> %~dp0report.log

            IF ERRORLEVEL 1 ECHO Station %LWN%,Workstation %WKSTN%, A READ/WRITE ERROR OCCURRED >> %~dp0report.log
echo logwrite error 1 complete
            popd
        )
    )
    IF ERRORLEVEL 1 (
        ECHO ,,SYSTEM IS OFFLINE >> %~dp0report.log

        )
    popd
    set wkstn=
    set lwn=
    echo pop d complete
    )
msg %username% Script run complete...
eof

Upvotes: 0

Views: 71

Answers (2)

Aacini
Aacini

Reputation: 67206

Although your code have several issues, the main one is the use of % instead of ! when you access the value of variables modified inside a for loop (although you already have the "enabledelayedexpansion" part in setlocal command). However, I noted that you sometimes use the FOR replaceable parameter (like in --replace "%%I") and sometimes you use the variable with the same value (%LWN%), so a simpler solution in your case would be to replace every %VAR% with its corresponding %%A for parameter.

I inserted this modification in your code besides a couple small changes that make the code simpler and clearer.

@ECHO ON
setlocal

> "%~dp0report.log" ECHO Batch Script executed on %DATE% at %TIME%

rem Read computer list line by line and do
FOR /F %%A in (%~dp0workstations.txt) do (

    rem Connect to workstation and read lwn.txt file
    pushd "\\%%A\c$\"

    IF NOT ERRORLEVEL 1 (
        FOR /F "usebackq" %%I in ("\\%%A\c$\support\lwn.txt") DO (

            %~dp0fnr.exe --cl --dir "\\%%A\c$\support\folder\config" --fileMask "file.xml" --find "21XXXX" --replace "%%I"

            IF NOT ERRORLEVEL 1 (
                ECHO Station %%I,Workstation %%A,Completed Successfully >> %~dp0report.log
            ) ELSE (
                ECHO Station %%I,Workstation %%A, A READ/WRITE ERROR OCCURRED >> %~dp0report.log
                echo logwrite error 1 complete
            )
        )
    ) ELSE (
        ECHO ,,SYSTEM IS OFFLINE >> %~dp0report.log
    )

    popd
    echo pop d complete

)
msg %username% Script run complete...

Upvotes: 2

lit
lit

Reputation: 16226

The ! notation must be used on all variables that are changed inside the loop.

C:>type looptest.bat
@ECHO OFF
setlocal enabledelayedexpansion

rem read computer list line by line and do
FOR /F %%A in (%~dp0workstations.txt) do (
    SET WKSTN=%%A

    ECHO WKSTN is set to %WKSTN%
    ECHO WKSTN is set to !WKSTN!

    pushd "\\!WKSTN!\c$\"

    ECHO After PUSHD, ERRORLEVEL is set to %ERRORLEVEL%
    ECHO After PUSHD, ERRORLEVEL is set to !ERRORLEVEL!

    IF !ERRORLEVEL! NEQ 0 (
        ECHO ,,SYSTEM IS OFFLINE
    ) ELSE (
        ECHO Host !WKSTN! is available
    )

    popd
)
EXIT /B 0

The workstations.txt file contained the following. (I should not give out actual host names.)

LIVEHOST1
DEADHOST1
LIVEHOST2

The output is...

C:>call looptest.bat
WKSTN is set to
WKSTN is set to LIVEHOST1
After PUSHD, ERRORLEVEL is set to 0
After PUSHD, ERRORLEVEL is set to 0
Host LIVEHOST1 is available
WKSTN is set to
WKSTN is set to DEADHOST1
The network path was not found.
After PUSHD, ERRORLEVEL is set to 0
After PUSHD, ERRORLEVEL is set to 1
,,SYSTEM IS OFFLINE
WKSTN is set to
WKSTN is set to LIVEHOST2
After PUSHD, ERRORLEVEL is set to 0
After PUSHD, ERRORLEVEL is set to 0
Host LIVEHOST2 is available

Upvotes: 2

Related Questions