Jak uruchomić wiele plików .BAT w pliku .BAT

695

Próbuję zmusić mnie commit-build.batdo wykonania innych plików .BAT w ramach naszego procesu kompilacji.

Treść commit-build.bat:

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

Wydaje się to dość proste, ale commit-build.batwykonuje tylko pierwszy element na liście ( msbuild.bat).

Uruchomiłem każdy z plików osobno, bez żadnych problemów.

Yvette
źródło
4
@sean - Nie musisz instalować pełnego pakietu Cygwin, aby narzędzia wiersza poleceń działały. Po prostu wyjmij wszystkie dll cygwin z pakietu, umieść je w katalogu z łatkami, umieść wszystkie narzędzia w innym katalogu z łatkami i możesz zacząć.
Techie Joe,
zakładając, że każdy z tych plików jest tylko wsadowy, dlaczego nie po prostu umieścić ich w jednym dużym pliku i użyć funkcji limitu czasu, aby zezwolić na każdym uruchomieniu.
CMS_95

Odpowiedzi:

1201

Posługiwać się:

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

Gdy nie jest używane CALL, bieżący plik wsadowy zatrzymuje się, a wywoływany plik wsadowy rozpoczyna wykonywanie. Jest to szczególne zachowanie sięgające wczesnych dni MS-DOS.

Philippe Leybaert
źródło
dziwne, próbowałem bez „wywołania” na Windows 7 i pamiętam, że zadziałało, ale na Windows XP wymagało tego polecenia. czy to możliwe?
programista Androida
7
Bez wywołania, zgodnie z oryginalną specyfikacją DOS, powinien wykonywać łańcuchy poleceń i NIE powracać. Popularną opcją przed dodaniem „CALL” było otwarcie podrzędnego wiersza polecenia, takiego jak „polecenie / c second.bat”, ponieważ to również zwróci.
Brian Knoblauch
1
Miałem problem z przedsiębiorczością na Windows 7, więc nie chodzi tylko o XP
Rafiki
7
W systemie Windows 10 wykonywana jest tylko pierwsza linia. Odpowiedź farheen jednak zadziałała.
robro
2
Jak przekazać parametry do plików wsadowych, a jednym z parametrów jest ścieżka ze spacjami.
Zeus
180

Wszystkie pozostałe odpowiedzi są poprawne: użyj połączenia. Na przykład:

 call "msbuild.bat"

Historia

W starożytnych wersjach DOS rekurencyjne wykonywanie plików wsadowych było niemożliwe. Następnie wprowadzono polecenie call, które wywołało kolejną powłokę cmd w celu wykonania pliku wsadowego i po zakończeniu zwróciło wykonanie z powrotem do wywołującej powłoki cmd.

Oczywiście w późniejszych wersjach żadna inna powłoka cmd nie była już potrzebna.

Na początku wiele plików wsadowych zależało od tego, że wywołanie pliku wsadowego nie powróci do wywoływanego pliku wsadowego. Zmiana tego zachowania bez dodatkowej składni spowodowałaby uszkodzenie wielu systemów, takich jak systemy menu wsadowego (używanie plików wsadowych do struktur menu).

Dlatego, podobnie jak w wielu przypadkach z Microsoftem, zgodność z poprzednimi wersjami jest przyczyną tego zachowania.

Porady

Jeśli pliki wsadowe mają spacje w nazwach, użyj cudzysłowów wokół nazwy:

call "unit tests.bat"

Nawiasem mówiąc: jeśli nie masz wszystkich nazw plików wsadowych, możesz również użyć do tego (nie gwarantuje to prawidłowej kolejności wywołań plików wsadowych; postępuje zgodnie z kolejnością systemu plików):

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

Możesz także reagować na poziomy błędu po połączeniu. Posługiwać się:

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

zwrócić poziom błędu. 0 oznacza prawidłowe wykonanie. W wywoływanym pliku wsadowym możesz zareagować za pomocą

if errorlevel neq 0 <batch command>

Użyj, if errorlevel 1jeśli masz starszy system Windows niż NT4 / 2000 / XP, aby wyłapać wszystkie poziomy błędu 1 i wyższe.

Aby kontrolować przepływ pliku wsadowego, jest goto :-(

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

Jak zauważyli inni: spójrz na systemy kompilacji zastępujące pliki wsadowe.

Ralph M. Rickenbach
źródło
zgodził się, ale pętla może w tym przypadku przetwarzać pliki w niewłaściwej (alfabetycznej?) kolejności
Dave Archer
Ładna i bardzo kompletna odpowiedź. Jeśli włączasz przepływ kontrolny, warto zauważyć, że zamiast goto można wykonywać podprogramy za pomocą call: label1, a instrukcja „return” w plikach wsadowych jest nieco dziwnym goto: eof (i nie trzeba zrób sam etykietę eof, która istnieje domyślnie).
Legolas
errorlevelprzykład polecenie dał mi problem w Windows 10 (w konsoli cmd). Po prostu zmodyfikowałem polecenie if errorlevel neq echo Houston We have a Problem!. Mój proces wsadowy nie miał problemów i zakończył się w większości normalnie, ale na każdym kroku, w którym użyłem tego polecenia po instrukcji call, otrzymałem „neq było w tej chwili nieoczekiwane”. Myśląc, że może nie zmieniły równy składni, próbowałem !=, a także <>, ale ciągle się ten sam „nie oczekuje w tej chwili” błąd dla nowej składni. co mogłem robić źle?
TMWP
118

Jeśli chcemy otworzyć wiele podpowiedzi poleceń, moglibyśmy użyć

start cmd /k

/k: jest obowiązkowy, który zostanie wykonany.

Uruchamianie wielu wierszy poleceń można wykonać jak poniżej.

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.
farheen
źródło
7
właśnie tego szukaliśmy, ponieważ nasza pierwsza aplikacja blokuje konsolę, dzięki za podpowiedź
Michael Moeller
1
spowoduje to uruchomienie wielu instancji polecenia, a nawet będzie działać w przypadku uruchamiania wielu plików wsadowych z <pauzą>. +1, ponieważ właśnie tego szukałem!
Christian Noel
5
czy mógłbyś wyjaśnić, że te liczby są w twojej odpowiedzi? Ich cel nie jest jasny.
Kalamalka Kid
3
Zauważ, że większość ludzi prawdopodobnie chce używać start "Window title" /wait cmd /k call something.batdo uruchamiania rzeczy w kolejności sekwencyjnej.
Andrew
3
(lub start "Window title" /wait cmd /c something.bat, gdzie cmd /czamyka okno po zakończeniu)
Andrew
42

Próbować:

call msbuild.bat
call unit-tests.bat
call deploy.bat
Jonathan
źródło
28

Wywołujesz wiele partii w celu skompilowania programu. Przyjmuję za pewnik, że jeśli wystąpi błąd:
1) Program w pakiecie zakończy działanie z poziomem błędu ;
2) Chcesz się o tym dowiedzieć.

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

„||” sprawdza poziom błędu wyższy niż 0. W ten sposób wszystkie partie są wywoływane w kolejności, ale zatrzymają się przy każdym błędzie, pozostawiając ekran bez zmian.

Sójka
źródło
23

Jeśli mamy dwa skrypty wsadowe, aaa.bat i bbb.bat, i wywołujemy jak poniżej

call aaa.bat
call bbb.bat

Podczas wykonywania skryptu najpierw wywoła aaa.bat, zaczeka na zakończenie wątku aaa.bat i wywoła bbb.bat.

Ale jeśli nie chcesz czekać na zakończenie aaa.bat w celu wywołania bbb.bat, spróbuj użyć polecenia START :

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

Egzamin:

start /b aaa.bat
start /b bbb.bat
użytkownik2314621
źródło
22
call msbuild.bat
call unit-tests.bat
call deploy.bat
kurczaka w maśle
źródło
20

Aby wywołać .batplik w .batpliku, użyj

call foo.bat

(Tak, to głupie, byłoby bardziej sensowne, gdybyś mógł to wywołać foo.bat, tak jak z wiersza poleceń, ale poprawnym sposobem jest użycie call.)

Zifre
źródło
7

Patrząc na nazwy plików, czy zastanawiałeś się nad użyciem narzędzia do kompilacji, takiego jak NAnt lub Ant (wersja Java). Otrzymasz o wiele większą kontrolę niż w przypadku plików nietoperzy.

Dave Archer
źródło
7

Jeśli chcesz otworzyć wiele plików wsadowych jednocześnie, możesz użyć polecenia call. Jednak polecenie połączenia zamyka bieżący plik nietoperza i przechodzi do innego. Jeśli chcesz otworzyć wiele jednocześnie, możesz spróbować:

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

I tak dalej lub powtórz start cmdcall...” dla dowolnej liczby plików. Działa to w systemie Windows 7 , ale nie jestem pewien co do innych systemów.

CMS_95
źródło
6
Start msbuild.bat
Start unit-tests.bat
Start deploy.bat

Jeśli to nie zadziała, należy wymienić startz calllub spróbuj tego:

Start msbuild.bat
Goto :1
:1
Start unit-tests.bat
Goto :2
:2
Start deploy.bat
McOussKing
źródło
3

Wystarczy użyć callpolecenia! Oto przykład:

call msbuild.bat
call unit-tests.bat
call deploy.bat
PryroTech
źródło
3

Przy prawidłowym cytowaniu (czasami może to być trudne):

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

1st arg - Title (w tym przypadku pusty)
2nd arg - / D określa katalog startowy, można go pominąć, jeśli chcesz, aby bieżący katalog działał (np. „% ~ Dp0”)
3. arg - polecenie uruchomienia, „cmd.exe”
4th arg - argumenty do polecenia, z podwojonymi cudzysłowami dla argumentów w środku (w ten sposób unikasz cudzysłowów w cudzysłowach wsadowo)

robertcollier4
źródło
2

Uruchamiając wiele skryptów w jednym miałem ten sam problem. Utrzymywałem, że umiera na pierwszym, nie zdając sobie sprawy, że kończy się na pierwszym skrypcie.

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

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

Usunąłem wszystkie 11 wierszy EXIT skryptu i próbowałem ponownie, a wszystkie 11 działały kolejno po kolei w tym samym oknie poleceń.

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

::ScriptA.bat
Do Foo

::ScriptB.bat
Do bar
John Oliphant
źródło
nie usuwaj exits, goto :eofzamiast tego zastąp je . Będzie to "powrót" docall
Stephan
zdajesz sobie sprawę, że w prostej partii polecenia będą uruchamiane w kolejności, w której są nazywane także podstawowym układem indeksów. @echo off :menu some commands goto menuPamiętaj, że będzie to ciągła pętla, dopóki nie zostanie zamknięta. w zasadzie nie potrzebujesz ::sprawiedliwego:
CMS_95
0

Następujące rozwiązanie rozwiązało mój problem:

start call "batch1.bat"
start call "batch2.bat"
Quinn
źródło
0

Może chcesz tego:

Uruchom skrypty wsadowe równolegle

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

Tutaj trzy pliki wsadowe są uruchamiane w osobnych oknach poleceń w stanie zminimalizowanym. Jeśli nie chcesz ich minimalizować, usuń je /min. Ponadto, jeśli nie będziesz musiał kontrolować ich później, możesz pozbyć się tytułów. Tak więc polecenie bez kości będzie…start cmd /k call systemLogCollector.bat


Jeśli chcesz je rozwiązać-

taskkill /FI "WindowTitle eq appLogCollector*" /T /F
taskkill /FI "WindowTitle eq uiLogCollector*" /T /F
taskkill /FI "WindowTitle eq systemLogCollector*" /T /F
Minhas Kamal
źródło