Могу ли я иметь блок IF в пакетном файле DOS?
В пакетном файле DOS мы можем иметь только 1 строку, если тело оператора? Я думаю, что нашел где-то, что я мог бы использовать ()
для блока if так же, как {}
, используемого в языках программирования C, но он не выполняет инструкции, когда я это пробую. Сообщения об ошибках отсутствуют. Этот мой код:
if %GPMANAGER_FOUND%==true(echo GP Manager is up
goto Continue7
)
echo GP Manager is down
:Continue7
Странно, что ни "GP Manager не работает", ни "GP Manager не работает" печатается при запуске командного файла.
Ответы
Ответ 1
Вы действительно можете поместить создание блока операторов для выполнения после условного. Но у вас синтаксис неправильный. Скобки должны использоваться точно так, как показано:
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
, как тест. Подробнее здесь
Ответ 2
Логически, ответ Коди должен работать. Однако я не думаю, что командная строка логически обрабатывает блок кода. Для жизни меня я не могу заставить это работать должным образом с помощью одной команды внутри блока. В моем случае обширное тестирование показало, что все команды внутри блока кэшируются и выполняются одновременно в конце блока. Это, конечно, не дает ожидаемых результатов. Вот упрощённый пример:
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
Вместо этого, попробуйте использовать амперсанд & или двойной амперсанд && (условно с уровнем ошибки 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"
)
Ответ 4
Я просмотрел эту статью в результатах, возвращаемых поиском, связанным с командой IF в пакетном файле, и я не мог устоять перед тем, чтобы исправить ошибочное представление о том, что блоки IF ограничены одиночными командами. Ниже приведена часть производственной команды Windows NT script, которая запускается ежедневно на машине, на которой я составляю этот ответ.
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), показал только один -компонентные блоки. Поскольку приложение перешло в расширенное обслуживание (что означает, что я не принимаю активного участия в его поддержке), я не могу сказать, что это потому, что мне не нужно больше одной строки, или что я не могу заставить их работать.
Независимо, если последнее верно, существует простой способ обхода; переместите несколько строк в отдельный командный файл или подпрограмму пакетного файла. Я знаю, что последний работает в обоих сценариях.
Ответ 5
Может быть, немного поздно, но надеюсь, что это будет:
@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