Могу ли я иметь блок IF в командном файле DOS? - PullRequest
88 голосов
/ 13 февраля 2011

В пакетном файле DOS у нас может быть только 1 строка, если тело оператора?Я думаю, что где-то нашел, что мог бы использовать () для блока if точно так же, как {}, используемый в C-подобных языках программирования, но он не выполняет операторы, когда я пытаюсь это сделать.Нет сообщения об ошибке.Этот мой код:

if %GPMANAGER_FOUND%==true(echo GP Manager is up
goto Continue7
)
echo GP Manager is down
:Continue7

Как ни странно, ни «Диспетчер GP не работает», ни «Диспетчер GP не работает», когда я запускаю командный файл.

Ответы [ 5 ]

126 голосов
/ 13 февраля 2011

Вы действительно можете создать блок операторов для выполнения после условия.Но у вас неправильный синтаксис.Скобки должны использоваться точно так, как показано:

if <statement> (
    do something
) else (
    do something else
)

Однако я не верю, что существует какой-либо встроенный синтаксис для операторов else-if.К сожалению, вам нужно будет создать вложенные блоки операторов if, чтобы справиться с этим.


Во-вторых, этот %GPMANAGER_FOUND% == true тест выглядит мне подозрительно.Я не знаю, какая переменная окружения установлена ​​или как вы ее устанавливаете, но я очень сомневаюсь, что код, который вы показали, даст результат, который вы ищете.


Следующий пример кода хорошо работает для меня:

@echo off

if ERRORLEVEL == 0 (
    echo GP Manager is up
    goto Continue7
)
echo GP Manager is down
:Continue7

Обратите внимание на несколько конкретных деталей о моем примере кода:

  • Пробел, добавленный между концом условного оператора,и открывающая скобка.
  • Я устанавливаю @echo off, чтобы не видеть всех операторов, выводимых на консоль по мере их выполнения, и вместо этого просто видеть выходные данные тех, которые специально начинаютсяс echo.
  • Я использую встроенную переменную ERRORLEVEL в качестве теста.Подробнее здесь
13 голосов
/ 07 января 2013

Логично, ответ Коди должен работать. Однако я не думаю, что командная строка обрабатывает блок кода логически. На всю жизнь я не могу заставить это работать должным образом с помощью одной команды внутри блока. В моем случае обширное тестирование показало, что все команды в блоке кэшируются и выполняются одновременно в конце блока. Это, конечно, не дает ожидаемых результатов. Вот упрощенный пример:

if %ERRORLEVEL%==0 (
set var1=blue
set var2=cheese
set var3=%var1%_%var2%
)

Это должно предоставить var3 следующее значение:

blue_cheese

но вместо этого выдает:

_

потому что все 3 команды кэшируются и выполняются одновременно при выходе из блока кода.

Мне удалось преодолеть эту проблему, переписав блок if для выполнения только одной команды - goto - и добавив несколько меток. Это неуклюже, и мне это не очень нравится, но, по крайней мере, это работает.

if %ERRORLEVEL%==0 goto :error0
goto :endif

:error0
set var1=blue
set var2=cheese
set var3=%var1%_%var2%

:endif
3 голосов
/ 21 сентября 2013

Вместо этого беспорядка попробуйте использовать амперсанд & или двойной амперсанд && (условно до уровня ошибки 0) в качестве разделителей команд.

Я исправил фрагмент сценария с помощью этого трюка, чтобы подвести итог, у меня есть три пакетных файла, один из которых вызывает два других после того, как обнаружил, какие буквы были назначены внешним резервным дискам. Я оставляю первый файл на основном внешнем диске, чтобы вызовы его подпрограммы резервного копирования работали нормально, но вызовы второго требовали активной смены диска. Код ниже показывает, как я это исправил:

for %%b in (d e f g h i j k l m n o p q r s t u v w x y z) DO (
if exist "%%b:\Backup.cmd" %%b: & CALL "%%b:\Backup.cmd"
)
1 голос
/ 12 июня 2016

Я наткнулся на эту статью в результатах, возвращаемых поиском, связанным с командой IF в командном файле, и я не мог удержаться от возможности исправить ошибочное представление о том, что блоки IF ограничены отдельными командами. Ниже приведен фрагмент производственного командного сценария Windows NT, который ежедневно запускается на компьютере, на котором я пишу этот ответ.

    if "%COPYTOOL%" equ "R" (
    WWLOGGER.exe "%APPDATA%\WizardWrx\%~n0.LOG" "Using RoboCopy to make a backup of %USERPROFILE%\My Documents\Outlook Files\*"
    %TOOLPATH% %SRCEPATH% %DESTPATH% /copyall %RCLOGSTR% /m /np /r:0 /tee
    C:\BIN\ExitCodeMapper.exe C:\BIN\ExitCodeMapper.INI[Robocopy] %TEMP%\%~n0.TMP %ERRORLEVEL%
) else (
    WWLOGGER.exe "%APPDATA%\WizardWrx\%~n0.LOG" "Using XCopy to make a backup of %USERPROFILE%\My Documents\Outlook Files\*"
    call %TOOLPATH%  "%USERPROFILE%\My Documents\Outlook Files\*" "%USERPROFILE%\My Documents\Outlook Files\_backups" /f /m /v /y
    C:\BIN\ExitCodeMapper.exe C:\BIN\ExitCodeMapper.INI[Xcopy] %TEMP%\%~n0.TMP %ERRORLEVEL%
)

Возможно, блоки из двух или более строк применяются исключительно к командным сценариям Windows NT (файлы .CMD), поскольку при поиске в каталоге производственных сценариев приложения, которое ограничено пакетными файлами старой школы (.BAT), обнаружен только один Командные блоки. Поскольку приложение перешло в расширенное обслуживание (то есть я не активно поддерживаю его), я не могу сказать, является ли это причиной того, что мне не нужно больше одной строки, или я не могу заставить их работать.

В любом случае, если последнее верно, существует простой обходной путь; переместите несколько строк в отдельный пакетный файл или в подпрограмму пакетного файла. Я знаю, что последний работает в обоих видах сценариев.

0 голосов
/ 13 сентября 2013

Может быть немного поздно, но надеюсь, что это поможет:

@echo off 

if %ERRORLEVEL% == 0 (
msg * 1st line WORKS FINE rem You can relpace msg * with any othe operation...
goto Continue1
)
:Continue1
If exist "C:\Python31" (
msg * 2nd line WORKS FINE rem You can relpace msg * with any othe operation...
    goto Continue2
)
:Continue2
If exist "C:\Python31\Lib\site-packages\PyQt4" (  
msg * 3th line WORKS FINE rem You can relpace msg * with any othe operation...
    goto Continue3
)
:Continue3
msg * 4th line WORKS FINE rem You can relpace msg * with any othe operation...
    goto Continue4
)
:Continue4
msg * "Tutto a posto" rem You can relpace msg * with any othe operation...
pause
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...