Пакет% errorlevel% возвращает 0 в цикле FOR - PullRequest
2 голосов
/ 21 августа 2011

Я пытаюсь сделать цикл, который будет проходить через набор текстовых файлов в указанном каталоге в поисках строки.Результат сообщается в зависимости от того, найдена ли строка.Но %errorlevel% всегда возвращает 0 и оценивается как 0.

SETLOCAL enabledelayedexpansion

    FOR %%G IN (*.txt) DO (
        find /i "My text string" "%%G"
        ECHO %date% %time% :  errorlevel is %errorlevel% >> %report_dir%\%computername%.txt
        IF %errorlevel% EQU 1 (
            ECHO %date% %time% : String found >> %report_dir%\%computername%.txt

            GOTO:copy_log
        )

    )

    ENDLOCAL

Раймон, ты это имел ввиду?

Ответы [ 4 ]

8 голосов
/ 21 августа 2011

%ERRORLEVEL% расширяется слишком рано. Вы можете просто избежать этой проблемы, используя:

IF ERRORLEVEL 1

Или для получения дополнительной информации см. Это объяснение «отложенного расширения переменной среды» из SET /? справочного текста:

Наконец, поддержка отложенного расширения переменной среды была добавлено. Эта поддержка всегда отключена по умолчанию, но может быть включается / отключается с помощью командной строки /V и переключается на CMD.EXE. Смотри CMD /?

Задержка расширения переменной среды полезна для обхода ограничения текущего расширения, которое происходит, когда линия текст читается, а не когда он выполняется. Следующий пример демонстрирует проблему с немедленным расширением переменной:

    set VAR=before
    if "%VAR%" == "before" (
        set VAR=after
        if "%VAR%" == "after" @echo If you see this, it worked
    )

никогда не будет отображать сообщение, так как %VAR% в обоих операторах IF подставляется при чтении первого оператора IF, так как он логически включает в себя тело IF, которое является составным оператором. Итак, ЕСЛИ внутри составного оператора действительно сравнивает «до» с «после», которое никогда не будет равным. Аналогично, следующий пример не будет работать должным образом:

    set LIST=
    for %i in (*) do set LIST=%LIST% %i
    echo %LIST%

в том смысле, что он НЕ будет создавать список файлов в текущем каталоге, но вместо этого просто установите переменную LIST для последнего найденного файла. Опять же, это потому, что% LIST% раскрывается только один раз, когда FOR оператор читается, и в это время переменная LIST пуста. Итак фактический цикл FOR, который мы выполняем:

    for %i in (*) do set LIST= %i

, который просто устанавливает LIST для последнего найденного файла.

Задержка расширения переменной среды позволяет использовать другой символ (восклицательный знак), чтобы раскрыть переменные среды в время исполнения. Если включено замедленное расширение переменной, выше примеры могут быть написаны следующим образом, чтобы работать как задумано:

    set VAR=before
    if "%VAR%" == "before" (
        set VAR=after
        if "!VAR!" == "after" @echo If you see this, it worked
    )

Опять же, это потому, что% LIST% раскрывается только один раз, когда FOR оператор читается, и в это время переменная LIST пуста. Итак фактический цикл FOR, который мы выполняем:

    for %i in (*) do set LIST= %i

, который просто устанавливает LIST для последнего найденного файла.

Задержка расширения переменной среды позволяет использовать другой символ (восклицательный знак), чтобы раскрыть переменные среды в время исполнения. Если включено замедленное расширение переменной, выше Примеры могут быть написаны следующим образом, чтобы работать как задумано:

    set VAR=before
    if "%VAR%" == "before" (
        set VAR=after
        if "!VAR!" == "after" @echo If you see this, it worked
    )

    set LIST=
    for %i in (*) do set LIST=!LIST! %i
    echo %LIST%
4 голосов
/ 22 августа 2011

Я предпочитаю делать For ответвления циклов.Это предотвращает проблемы с переменным расширением:

For %%G In (*.txt) Do Call :ScanFile "%%G"
Exit /B

:ScanFile
Find /i "My text string" "%~1"
If %ErrorLevel%==1 (
    Echo %date% %time% : String found >> %report_dir%\%computername%.txt
    Goto :CopyLog
)
Exit /B

:CopyLog
...
Exit /B
2 голосов
/ 21 августа 2011

Как говорит Рэймонд, вы оцениваете% ERRORLEVEL% для эха, который почти всегда (никогда не говорит никогда) возвращает 0.

Что-то вроде следующего будет лучше:

FOR %%G IN (*.txt) DO (
    find /i "My text string" "%%G"
    SET error = %errorlevel% 
    ECHO %date% %time% :  errorlevel is %errorl% >> %report_dir%\%computername%.txt
    IF %error% EQU 1 (
        ECHO %date% %time% : String found >> %report_dir%\%computername%.txt
        GOTO:copy_log
    )
)
0 голосов
/ 04 февраля 2016

У меня была такая же проблема при циклическом просмотре ключей / значений реестра, и я пришел к этому сообщению.У моего "reg запроса" всегда было ERRORLEVEL 0 в цикле for.

Вот мое решение:

for %%s in (%ToBeUninstalled%) do ( REG QUERY "%KEY64%\%%s" | find /i "UninstallString" > NUL && (msiexec.exe /x %%s /qb) || (echo Software not installed) )

KEY64 - HKLM \ SOFTWARE \ Wow6432Node \ Microsoft \ Windows\ CurrentVersion \ Uninstall

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...