могу ли я иметь блок if в командном файле dos?

<p>в пакетном файле dos мы можем иметь только 1 строку, если тело оператора? я думаю, что где-то нашел, что мог бы использовать <code>()</code> для блока if точно так же, как <code>{}</code>, используемый в c-подобных языках программирования, но он не выполняет операторы, когда я пытаюсь это сделать. нет сообщения об ошибке. это мой код:</p><pre><code>if %gpmanager\_found%==true(echo gp manager is up goto continue7 ) echo gp manager is down :continue7 </code></pre><p>как ни странно, ни «диспетчер gp не работает», ни «диспетчер gp не работает» печатается, когда я запускаю командный файл.</p>

<p>вы действительно можете создать блок операторов для выполнения после условия. но у вас неправильный синтаксис. скобки должны использоваться точно так, как показано:</p><pre><code>if <statement> ( do something ) else ( do something else ) </code></pre><p>однако я не верю, что существует какой-либо встроенный синтаксис для операторов <code>else-if</code>. к сожалению, вам придется создавать вложенные блоки операторов <code>if</code>, чтобы справиться с этим.</p><p><br> во-вторых, этот тест на <code>%gpmanager\_found% == true</code> выглядит очень подозрительно для меня. я не знаю, какая переменная окружения установлена или как вы ее устанавливаете, но я очень сомневаюсь, что код, который вы показали, даст результат, который вы ищете.</p><p><br> следующий пример кода отлично работает для меня:</p><pre><code>@echo off if errorlevel == 0 ( echo gp manager is up goto continue7 ) echo gp manager is down :continue7 </code></pre><p>обратите внимание на несколько конкретных деталей о моем примере кода:</p><ul> <li>пробел, добавленный между концом условного оператора и открывающей скобкой.</li> <li>я устанавливаю <code>@echo off</code>, чтобы не видеть <em>all</em> операторов, напечатанных на консоли, по мере их выполнения, и вместо этого просто видеть вывод тех, которые конкретно начинаются с <code>echo</code>.</li> <li>я использую встроенную переменную <code>errorlevel</code> в качестве теста. читать дальше <a href="http://www.robvanderwoude.com/errorlevel.php">здесь</a> </li> </ul>

<p>по логике вещей, ответ коди<em> должен </em>работает. однако я не думаю, что командная строка обрабатывает блок кода логически. на всю жизнь я не могу заставить это работать должным образом с помощью одной команды внутри блока. в моем случае расширенное тестирование показало, что все команды в блоке кэшируются и выполняются одновременно в конце блока. это, конечно, не дает ожидаемых результатов. вот упрощенный пример:</p><pre><code>if %errorlevel%==0 ( set var1=blue set var2=cheese set var3=%var1%\_%var2% ) </code></pre><p>это<em> должно </em>предоставить var3 следующее значение:</p><pre><code>blue\_cheese </code></pre><p>но вместо этого дает:</p><pre><code>\_ </code></pre><p>потому что все 3 команды кэшируются и выполняются одновременно при выходе из блока кода. </p><p>я смог преодолеть эту проблему, переписав блок if для выполнения только одной команды - goto - и добавив несколько меток. это неуклюже, и мне это не очень нравится, но, по крайней мере, это работает.</p><pre><code>if %errorlevel%==0 goto :error0 goto :endif :error0 set var1=blue set var2=cheese set var3=%var1%\_%var2% :endif </code></pre>

<p>может быть, немного поздно, но надеюсь, что это поможет</p><pre><code>@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 </code></pre>

<p>вместо этого, попробуйте использовать амперсанд & или двойной амперсанд && (условно с уровнем ошибки 0) в качестве разделителей команд.</p><p>я исправил фрагмент сценария с помощью этого трюка, чтобы подвести итог, у меня есть три пакетных файла, один из которых вызывает два других после того, как обнаружил, какие буквы были назначены внешним резервным дискам. я оставляю первый файл на основном внешнем диске, чтобы вызовы его подпрограммы резервного копирования работали нормально, но вызовы второго требовали активной замены диска. код ниже показывает, как я это исправил:</p><p>для %% b в (d e f g h i j k lm n o p q r s t u v w x y z) do ( если существует "%% b:\backup.cmd" %% b: & call "%% b:\backup.cmd" )</p>

<p>я наткнулся на эту статью в результатах, возвращаемых поиском, связанным с командой if в пакетном файле, и я не мог удержаться от возможности исправить ошибочное представление о том, что блоки if ограничены отдельными командами. ниже приведен фрагмент производственного командного сценария windows nt, который выполняется ежедневно на компьютере, на котором я пишу этот ответ.</p><pre><code> 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% ) </code></pre><p>возможно, блоки из двух или более строк применяются исключительно к командным сценариям windows nt (файлы .cmd), поскольку при поиске в каталоге производственных сценариев приложения, которое ограничено пакетными файлами старой школы (.bat), обнаружены только блоки с одной командой , поскольку приложение перешло в расширенное обслуживание (то есть я не активно поддерживаю его), я не могу сказать, является ли это причиной того, что мне не нужно больше одной строки, или я не могу заставить их работать.</p><p>независимо от того, если последнее верно, существует простой обходной путь; переместите несколько строк в отдельный пакетный файл или подпрограмму пакетного файла. я знаю, что последний работает в обоих видах сценариев.</p>