Вложенный IF (IF (...) ELSE (..)) оператор в пакетном режиме

Я пытаюсь написать инструкцию IF ELSE, вложенную в другой оператор IF. Вот что у меня есть:

IF %dirdive%==1 ( 
    IF DEFINED log (
        ECHO %DATE%, %TIME% >> %log%
        FOR /R %root1% %%G IN (.) DO (
            SET _G=%%G
            CALL :TESTEVERYTHING !_G:~0,-1! %root1% %root2% %log%
        )
        GOTO :end
    ) ELSE ( 
        ECHO %DATE%, %TIME%
        FOR /R %root1% %%G IN (.) DO (
            SET _G=%%G
            CALL :TESTEVERYTHINGnolog !_G:~0,-1! %root1% %root2%
        )
        GOTO :end
    )
)

Когда log не определен, я получаю:

The syntax of the command is incorrect.
ECHO Wed 07/18/2012, 15:50:12.34 >>

Aaaand Я в недоумении. Я пробовал играть со скобками. Я переместил последнее) на ту же строку, что и перед ней, и она не работает. Дело в том, что он отлично работает при определении log. Кажется, он разрывается сразу после или при IF %dirdive%==1, так как он не получит команду echo, вставленную сразу после этого.

Ответы

Ответ 1

Источником вашей проблемы является то, что даже если ветвь оператора IF не выполняется, он все равно должен иметь действительный синтаксис.

Если log не определено, то следующая строка

ECHO %DATE%, %TIME% >> %log%

расширяется до следующего значения log undefined

ECHO someDate, someTime >>

После перенаправления нет имени файла, что приводит к синтаксической ошибке.

Пока ваша переменная log еще не определена с закрытыми кавычками (когда она определена), просто измените ее следующим образом:

ECHO %DATE%, %TIME% >> "%log%"

Эта строка расширяется до следующего значения log undefined

ECHO someDate, someTime >> ""

Какой действительный синтаксис. Он не сработает с ошибкой "Ошибка системы не найден путь", если она выполнена, но она не будет выполняться, поскольку журнал undefined: -)

ИЗМЕНИТЬ

Возможно, лучшим решением является определение новой переменной, которая включает оператор перенаправления в значение, если и только если определено log. Тогда вам даже не нужен ваш большой оператор IF, и код легче поддерживать.

SET "redirect="
IF DEFINED log SET "redirect=>>!log!"
IF %dirdive%==1 (
  ECHO %DATE%, %TIME% %redirect%
  FOR /R %root1% %%G IN (.) DO (
    SET _G=%%G
    CALL :TESTEVERYTHING !_G:~0,-1! %root1% %root2% %log%
  )
  GOTO :end
)

Обратите внимание, что нормальное расширение %redirect% должно использоваться в инструкции ECHO. Отсроченное расширение !redirect! не будет работать, потому что фаза перенаправления парсера команд происходит до отложенного расширения.

Ответ 2

Другим решением является использование GOTO. Возможно, это не так элегантно, но легко понять.

IF %dirdive%==1 ( 
    IF DEFINED log GOTO logdefined ELSE GOTO nolog
)

:logdefined
ECHO %DATE%, %TIME% >> %log%
FOR /R %root1% %%G IN (.) DO (
    SET _G=%%G
    CALL :TESTEVERYTHING !_G:~0,-1! %root1% %root2% %log%
)
GOTO :end

:nolog
ECHO %DATE%, %TIME%
FOR /R %root1% %%G IN (.) DO (
    SET _G=%%G
    CALL :TESTEVERYTHINGnolog !_G:~0,-1! %root1% %root2%
)
GOTO :end

Ответ 3

Измените IF DEFINED log на: IF EXIST log. Для меня работает следующее:

echo off
set log=log.txt
set /p dirdive= Enter a directory:
IF %dirdive%==1 ( 
    IF EXIST %log% (
        ECHO "in IF" %DATE%, %TIME% >> %log%
        FOR /R %root1% %%G IN (.) DO (
            SET _G=%%G
            CALL :TESTEVERYTHING !_G:~0,-1! %root1% %root2% %log%
        )
        GOTO :end
    ) ELSE ( 
        ECHO "in ELSE" %DATE%, %TIME%
        FOR /R %root1% %%G IN (.) DO (
            SET _G=%%G
            CALL :TESTEVERYTHINGnolog !_G:~0,-1! %root1% %root2%
        )
        GOTO :end
    )
)
:end

Ответ 4

****@SETLOCAL ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION****
IF %dirdive%==1 ( 
    IF DEFINED log (
        ECHO %DATE%, %TIME% >> ****!log!****
        FOR /R %root1% %%G IN (.) DO (
            SET _G=%%G
            CALL :TESTEVERYTHING !_G:~0,-1! %root1% %root2% ****!log!****
        )
        GOTO :end
    ) ELSE ( 
        ECHO %DATE%, %TIME%
        FOR /R %root1% %%G IN (.) DO (
            SET _G=%%G
            CALL :TESTEVERYTHINGnolog !_G:~0,-1! %root1% %root2%
        )
        GOTO :end
    )
)
****@ENDLOCAL****

Жоао Мак-Кормик

Ответ 5

@if not "%1" == "max" (start /MAX cmd /Q /C %0 max&X)ELSE title %random%&set C=1&set D=2&wmic process where name="cmd.exe" CALL setpriority "REALTIME">NUL&CLS
:Y
color %D%&ECHO %random%%C%%random%%random%%random%%random%6%random%9%random%%random%%random%%random%%random%%random%%random%%random%%random%
IF %C% EQU 46 (TIMEOUT /T 1 /NOBREAK>nul&set C=1&CLS&IF %D% EQU 9 (set D=1)ELSE set /A D=%D%+1)ELSE set /A C=%C%+1
goto Y

`