'对于'循环变量不会在循环迭代中释放

时间:2015-05-09 15:22:49

标签: batch-file for-loop scripting

整夜破坏我的大脑试图找出为什么这不起作用,但我的一个变量在我的循环的下一次迭代中没有释放,我无法弄清楚为什么...循环的第一遍似乎工作正常,但是下一次迭代,第一个变量被锁定,脚本连接到已经配置的系统。

我现在已经盯着这一段时间,无论我如何接近它,它仍然表现得很糟糕。 :/目的是读取给定文件的文本字符串,并使用它来修改(通过查找和替换(fnr.exe))具有所需数据的多个实例的另一个文件。我没有很多运气与“发现”有关。替换了所需的文本实例,所以我使用了之前使用过的工具,似乎在以前的脚本应用程序中运行得非常好...

说实话,我发现自己很多时候都会遇到最基本的代码,所以任何一个愿意传授一些智慧/帮助的善良的人都会非常感激!

提前致谢...

@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

2 个答案:

答案 0 :(得分:2)

!必须在循环内更改的所有变量上使用表示法。

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

workstations.txt文件包含以下内容。 (我不应该透露实际的主机名。)

LIVEHOST1
DEADHOST1
LIVEHOST2

输出是......

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

答案 1 :(得分:2)

虽然您的代码有几个问题,但主要的一个是在访问for循环中修改的变量值时使用%而不是!(尽管您已经拥有“enabledelayedexpansion”参与setlocal命令)。但是,我注意到您有时使用FOR可替换参数(如--replace "%%I"中),有时您使用具有相同值(%LWN%)的变量,因此在您的情况下更简单的解决方案将是替换每个%VAR%及其对应的%%A参数。

我在代码中插入了这个修改,除了一些小的更改,使代码更简单,更清晰。

@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...