Подтвердить что ты не робот

"Позвонить" или "Не звонить" командному файлу?

Если изнутри файла bat вы вызвали другой пакетный файл, но все еще осталось выполнить несколько оставшихся операций, как вы можете убедиться, что вызов первого файла bat после завершения или ошибки вернется к файлу, который его вызвал в первом случае?

Пример:

CD:\MyFolder\MyFiles
Mybatfile.bat

Copy afile toHere

или

CD:\MyFolder\MyFiles
CALL Mybatfile.bat

COPY afile toHere

В чем разница между использованием CALL или START или ни с одним из них? Будет ли это иметь какое-либо влияние на то, будет ли оно возвращаться для результатов команды копирования или нет?

4b9b3361

Ответ 1

Как говорили другие, CALL является обычным способом вызова другого файла bat в байте и возврата к вызывающему.

Однако вся обработка пакетного файла прекратится (управление не вернется к вызывающему абоненту), если пакетный файл CALLed имеет фатальную синтаксическую ошибку или если CALLed script завершает работу с EXIT без опции /B.

Вы можете гарантировать, что управление вернется к вызывающему абоненту (пока окно консоли остается открытым), если вы выполните второй script с помощью команды CMD.

cmd /c "calledFile.bat"

Но это имеет ограничение, что переменные среды, заданные вызываемой группой, не будут сохранены после возврата.

Я не знаю о хорошем решении, гарантирующем возврат во всех случаях и сохранении изменений среды.

Если вам действительно нужно сохранять переменные при использовании CMD, тогда вы можете "вызвать" script записать переменную в файл temp, а затем вызвать, чтобы вызывающий абонент прочитал временный файл и заново установил переменные.

Ответ 2

call необходим для файлов .bat или .cmd, иначе элемент управления не вернется к вызывающему. Для файлов exe это не требуется.

Start не совпадает с call, он создает новый экземпляр cmd.exe, поэтому он может запускать вызываемый пакетный файл асинхронно

Ответ 3

Оператор `CALL 'был введен в MS-DOS 3.3

Он используется для вызова других пакетных файлов в пакетном файле без прерывания выполнения вызывающего пакетного файла и использования той же среды для обоих пакетных файлов.

Итак, в вашем случае решение должно использовать CALL

Ответ 4

Ладно, я даже не задумывался о том факте, что если вы вызываете пакет (независимо от типа, то есть .bat или .cmd), он не вернется, если вы этого не сделаете. использовать вызов.

Я сам использовал call, хотя по другой причине, что я на самом деле очень удивлен, что никто не поднял. Может быть, я пропустил это. МОЖЕТ, Я ЕДИНСТВЕННЫЙ В МИРЕ, КТО ЗНАЕТ !!: О

Наверное, нет, но я собираюсь опустить это знание здесь, потому что оно супер полезно.

Если вы используете вызов, вы можете использовать бинарные логические операторы, чтобы решить, как действовать на основе результата ERRORLEVEL. На самом деле, я всегда был поражен тем, как & и || существовал в DOS и не может быть использован таким образом. Ну, вот почему.

Самый простой способ проверить это - создать return.cmd с помощью блокнота или из командной строки следующим образом:

c:\> type con >return.cmd       

Теперь вы заметите, что курсор переходит на следующую строку и зависает. Введите:

@exit /B %1

А затем нажмите [ENTER], а затем [CTRL] - [Z], и этот файл будет создан. Хороший! Теперь вы можете попробовать следующие два примера:

call return.cmd 0 && echo Huzzah! A Complete Success! (Or cover up...)

call return.cmd 123 || echo Oops! Something happened. You can check ERRORLEVEL if you want the tinest amount of additional information possible.

И что? Что ж, запустите их снова, поменяв местами 0 и 123, и вы увидите, что сообщения НЕ печатаются.

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

     call return.cmd 0 && @(
         echo Batch says it completed successfully^^!
     ) || @(
         echo Batch completed, but returned a 'falsey' value of sort.
         call echo The specific value returned was: %ERRORLEVEL%
     )     

(Обратите внимание на "вызов" в разделе || перед вторым "эхом". Я полагаю, что именно так люди обошлись без задержки расширения в тот день. Если вы действительно включили задержку расширения (через. setlocal) EnableDelayedExpansion внутри пакета или запустить командную строку с cmd /v:on, тогда вы можете просто сделать! ERRORLEVEL !.)

... Здесь я должен извиниться и сказать, что если у вас в прошлом была травма if ERRORLEVEL, вам следует прекратить читать. Я понял Доверьтесь мне. Я думал о том, чтобы заплатить кому-то на fiverr, чтобы он набрал это удаленно, но для полноты картины я просто возьму один для команды и упомяну, что вы также можете сделать следующее, чтобы проверить уровень ошибки:

    if ERRORLEVEL 123 @echo QUICK! MOTHERS, COVER YOUR CHILDREN'S EYES! FINGERS ARE BEING UNDONE! :'(

Если вы никогда этого не печатали, то ХОРОШО! Вы будете жить дольше без необходимости читать, почему именно вы не получаете ожидаемых результатов. Жестокое слово, которое вы ищете, а не "причудливый".


Однако важная часть, которую я действительно хочу донести, заключается в том, что если вы попробуете это и НЕ будете использовать 'call', это ВСЕГДА выполнит ветку 'true'. Попробуйте сами!

Если я что-то упустил или вы знаете лучший способ сделать это, пожалуйста, дайте мне знать. Я люблю изучать такие вещи, как это!


Дополнительная информация, которую я упомянул:

В течение достаточно долгого времени я знал, что вы можете помещать перенаправления ДО команд таким образом:

    >nul echo. This won't be displayed!

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

    echo A B>file.txt C

И был ДЕЙСТВИТЕЛЬНО удивлен, обнаружив file.txt, который состоял из "A B C". Похоже, вы можете разместить их в любом месте, даже внутри команды. Я никогда не видел, чтобы кто-то делал это и не упоминал об этом, но я видел, как люди упоминали, что с ними можно поставить префикс строки.

Может быть, это ошибка исключительно для Windows 10 или что-то. Если у вас есть другая версия, и вы хотите попробовать ее, дайте мне знать, что мне будет интересно то, что вы узнаете.

Оставайся ботаником!