Як запустити декілька файлів .BAT у файлі .BAT


695

Я намагаюся змусити мене commit-build.batвиконувати інші файли .BAT як частина нашого процесу збирання.

Вміст commit-build.bat:

"msbuild.bat"
"unit-tests.bat"
"deploy.bat"

Це здається досить простим, але commit-build.batвиконує лише перший елемент у списку ( msbuild.bat).

Я запускав кожен з файлів окремо без проблем.


4
@sean - Вам не потрібно встановлювати повний пакет Cygwin, щоб змусити працювати утиліти командного рядка. Просто вийміть всі cygwin-коди з пакета, помістіть їх у виправлену папку, покладіть усі свої інструменти в інший промальований каталог і ви готові йти.
Течі Джо

припускаючи, що кожен з цих файлів є лише пакетним, чому б просто не помістити їх в один великий файл і використовувати функцію тайм-ауту, щоб дозволити кожен раз запускатися.
CMS_95

Відповіді:


1201

Використання:

call msbuild.bat
call unit-tests.bat
call deploy.bat

Якщо не використовується CALL, поточний пакетний файл зупиняється і викликаний пакетний файл починає виконувати. Це своєрідна поведінка, що датується ранніми днями MS-DOS.


дивно, я намагався без "дзвінка" на Windows 7, і я пам'ятаю, що він працював, але для Windows xp потрібна ця команда. це може бути?
андроїд розробник

7
Без виклику, відповідно до оригінальної специфікації DOS, слід виконати командування ланцюжка і НЕ повертатися. Популярним варіантом, перш ніж було додано "CALL", було відкриття дочірнього командного рядка типу "command / c second.bat", оскільки це також повернеться.
Брайан Кноблауш

1
У мене виникла проблема в Entreprise для Windows 7, тому це не лише xp
Рафікі,

7
У Windows 10 виконується лише перший рядок. Однак відповідь далекосяти спрацювала.
robro

2
Як передавати параметри до пакетних файлів, і один з парам - це шлях з пробілами.
Зевс

180

Усі інші відповіді правильні: використовуйте дзвінок. Наприклад:

 call "msbuild.bat"

Історія

У стародавніх версіях DOS рекурсивно не можна було виконувати пакетні файли. Тоді була введена команда виклику, яка викликала іншу оболонку cmd, щоб виконати пакетний файл і повернула виконання назад у викликову оболонку cmd, коли буде закінчена.

Очевидно, що в пізніших версіях більше жодної оболонки cmd більше не потрібна.

У перші дні багато пакетних файлів залежало від того, що виклик пакетного файлу не повернеться до викликового пакетного файлу. Змінення такої поведінки без додаткового синтаксису порушило б багато систем, таких як системи пакетного меню (використання пакетних файлів для структур меню).

Як і у багатьох випадках з Microsoft, тому зворотна сумісність є причиною такої поведінки.

Поради

Якщо у ваших пакетних файлах пробіли у своїх іменах, використовуйте лапки навколо імені:

call "unit tests.bat"

До речі: якщо у вас немає всіх назв пакетних файлів, ви можете також використовувати для цього (це не гарантує правильний порядок виклику пакетних файлів; це відповідає порядку файлової системи):

FOR %x IN (*.bat) DO call "%x"

Ви також можете реагувати на рівні помилок після дзвінка. Використання:

exit /B 1   # Or any other integer value in 0..255

щоб повернути рівень помилок. 0 позначає правильне виконання. У викликовому пакетному файлі ви можете реагувати за допомогою

if errorlevel neq 0 <batch command>

Використовуйте, if errorlevel 1якщо у вас старша Windows, ніж NT4 / 2000 / XP, щоб перехопити всі рівні помилок 1 і вище.

Для управління потоком пакетного файлу є goto :-(

if errorlevel 2 goto label2
if errorlevel 1 goto label1
...
:label1
...
:label2
...

Як зазначали інші: подивіться на системи побудови для заміни пакетних файлів.


погодилися, але цикл може в цьому випадку обробити файли в неправильному (за алфавітом?) порядку
Дейв Арчер

Гарна і дуже повна відповідь. Якщо ви включаєте контрольний потік, може бути добре зауважити, що замість goto, ви можете робити підпрограми, використовуючи call: label1, а оператор 'return' у пакетних файлах - це дещо дивне goto: eof (і не потрібно власноруч зробіть мітку eof, яка існує за замовчуванням).
Леголас

errorlevelприклад команди дав мені проблему на Windows 10 (в CMD консолі). Я змінив команду просто бути if errorlevel neq echo Houston We have a Problem!. Мій пакетний процес не мав жодних проблем і закінчувався здебільшого нормально, але кожен крок, коли я використовував цю команду після заяви про виклик, отримав "nq було несподівано в цей час". Думаючи, що вони, можливо, змінили нерівний синтаксис, я спробував, але !=також <>продовжував отримувати таку ж "не очікувану в даний час" помилку для нового синтаксису. що я можу робити не так?
TMWP

118

Якщо ми хочемо відкрити кілька командних підказок, тоді ми могли б використовувати

start cmd /k

/k: є обов'язковим, що буде виконуватися.

Запуск багатьох командних підказок можна зробити, як показано нижче.

start cmd /k Call rc_hub.bat 4444

start cmd /k Call rc_grid1.bat 5555

start cmd /k Call rc_grid1.bat 6666

start cmd /k Call rc_grid1.bat 5570.

7
саме це ми шукали, оскільки наш перший додаток блокує консоль, дякую за підказку
Майкл Моллер

1
це запустить кілька екземплярів команди і навіть буде працювати для запуску декількох пакетних файлів, у яких є <pause>. +1, оскільки це саме рішення, яке я шукав!
Крістіан Ноель

5
чи можете ви пояснити, що ці цифри є у вашій відповіді? Їх призначення його незрозуміле.
Каламалка Малюк

3
Зауважте, більшість людей, ймовірно, хочуть використовувати start "Window title" /wait cmd /k call something.batдля того, щоб керувати речами в послідовному порядку.
Андрій

3
(або start "Window title" /wait cmd /c something.batтам, де cmd /cзакриється вікно після закінчення)
Андрій


28

Ви викликаєте кілька партій, намагаючись скласти програму. Я сприймаю як належне, що якщо сталася помилка:
1) Програма всередині партії вийде з рівнем помилок ;
2) Ви хочете дізнатися про це.

for %%b in ("msbuild.bat" "unit-tests.bat" "deploy.bat") do call %%b|| exit /b 1

'||' тести на рівень помилок вище 0. Таким чином, всі партії викликаються в порядку, але зупиняються при будь-якій помилці, залишаючи екран таким, яким ви бачите будь-яке повідомлення про помилку.


23

Якщо у нас є два пакетні сценарії, aaa.bat і bbb.bat, і дзвоніть, як показано нижче

call aaa.bat
call bbb.bat

Виконуючи сценарій, він спочатку зателефонує aaa.bat, дочекається завершення потоку aaa.bat та зателефонує bbb.bat.

Але якщо ви не хочете чекати, коли aaa.bat припинить дзвінок bbb.bat, спробуйте скористатися командою START :

START ["title"] [/D path] [/I] [/MIN] [/MAX] [/SEPARATE | /SHARED]
  [/LOW | /NORMAL | /HIGH | /REALTIME | /ABOVENORMAL | /BELOWNORMAL]
  [/AFFINITY <hex affinity>] [/WAIT] [/B] [command/program]
  [parameters]

Іспит:

start /b aaa.bat
start /b bbb.bat


20

Щоб викликати .batфайл у .batфайлі, використовуйте

call foo.bat

(Так, це нерозумно. Було б більше сенсу, якби ви могли з ним зателефонувати foo.bat, як ви могли з командного рядка, але правильний спосіб - це використовувати call.)


7

Дивлячись на ваші імена файлів, чи обдумали ви використовувати інструмент збірки, як NAnt або Ant (версія Java). Ви отримаєте набагато більше контролю, ніж у файлах bat.


7

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

@echo off
start cmd "call ex1.bat&ex2.bat&ex3.bat"

І так далі або повторіть запуск cmd" call..." для будь-якої кількості файлів. Це працює для Windows 7 , але я не впевнений у інших системах.


6
Start msbuild.bat
Start unit-tests.bat
Start deploy.bat

Якщо це не працює, замініть startз callабо спробувати це:

Start msbuild.bat
Goto :1
:1
Start unit-tests.bat
Goto :2
:2
Start deploy.bat

3

Просто використовуйте callкоманду! Ось приклад:

call msbuild.bat
call unit-tests.bat
call deploy.bat

3

При правильному цитуванні (це може бути часом складно):

start "" /D "C:\Program Files\ProgramToLaunch" "cmd.exe" "/c call ""C:\Program Files\ProgramToLaunch\programname.bat"""

1-й аргумент - Заголовок (у цьому випадку порожній)
2-й аргумент - / D вказує стартовий каталог, його можна заборонити, якщо потрібно, щоб поточний робочий dir (наприклад, "% ~ dp0")
3-й аргумент - команда для запуску, "cmd.exe"
4-й arg - аргументи на команду, з подвоєними котируваннями аргументів всередині нього (саме так ви уникаєте лапок із цитат у пакеті)


2

Запуск декількох сценаріїв в одному у мене був той самий випуск. Я змусив його померти на першому, не розуміючи, що він виходить за першим сценарієм.

:: OneScriptToRunThemAll.bat
CALL ScriptA.bat
CALL ScriptB.bat
EXIT

:: ScriptA.bat
Do Foo
EXIT
::ScriptB.bat
Do bar
EXIT

Я видалив усі 11 моїх сценаріїв EXIT-рядків і спробував ще раз, і всі 11 запустили по черзі в одному вікні команди.

:: OneScriptToRunThemAll.bat
CALL ScriptA.bat
CALL ScriptB.bat
EXIT

::ScriptA.bat
Do Foo

::ScriptB.bat
Do bar

не видаляйте exits, замініть їх goto :eof. Це "повернеться" доcall
Стефана

ви розумієте, що в простих пакетних командах будуть виконуватись в тому порядку, який вони називаються також основним макетом для індексів @echo off :menu some commands goto menu. По суті, вам не потрібно ::просто:
CMS_95

0

Наступне вирішило мою проблему:

start call "batch1.bat"
start call "batch2.bat"

0

Можливо, ви хочете цього:

Запустіть пакетні сценарії паралельно-

start "systemLogCollector" /min cmd /k call systemLogCollector.bat
start "uiLogCollector" /min cmd /k call uiLogCollector.bat
start "appLogCollector" /min cmd /k call appLogCollector.bat

Тут три пакетні файли запускаються в окремих вікнах команд у мінімізованому стані. Якщо ви не хочете, щоб їх мінімізували, видаліть /min. Крім того, якщо вам не потрібно контролювати їх пізніше, ви можете позбутися від заголовків. Отже, команда з голою кісткою буде-start cmd /k call systemLogCollector.bat


Якщо ви хочете скасувати їх,

taskkill /FI "WindowTitle eq appLogCollector*" /T /F
taskkill /FI "WindowTitle eq uiLogCollector*" /T /F
taskkill /FI "WindowTitle eq systemLogCollector*" /T /F
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.