So führen Sie mehrere .BAT-Dateien in einer .BAT-Datei aus

694

Ich versuche, meine commit-build.bat.BAT-Dateien als Teil unseres Erstellungsprozesses auszuführen.

Inhalt von commit-build.bat:

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

Dies scheint einfach zu sein, führt jedoch commit-build.batnur das erste Element in der Liste aus ( msbuild.bat).

Ich habe jede der Dateien ohne Probleme einzeln ausgeführt.

Yvette
quelle
4
@sean - Sie müssen nicht das vollständige Cygwin-Paket installieren, damit die Befehlszeilen-Utils funktionieren. Nehmen Sie einfach alle Cygwin-DLLs aus dem Paket, platzieren Sie sie in einem Pfadverzeichnis, legen Sie alle Ihre Tools in einem anderen Pfadverzeichnis ab und los geht's.
Techie Joe
Angenommen, jede dieser Dateien ist nur ein Stapel, warum nicht einfach in eine große Datei einfügen und die Timeout-Funktion verwenden, um jedes Mal den Start zu ermöglichen.
CMS_95

Antworten:

1199

Verwenden:

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

Wenn Sie CALL nicht verwenden, wird die aktuelle Batchdatei gestoppt und die aufgerufene Batchdatei wird ausgeführt. Es ist ein eigenartiges Verhalten, das bis in die frühen MS-DOS-Tage zurückreicht.

Philippe Leybaert
quelle
seltsam, ich habe es ohne den "Aufruf" unter Windows 7 versucht und ich erinnere mich, dass es funktioniert hat, aber unter Windows XP erforderte es diesen Befehl. könnte es sein?
Android-Entwickler
7
Ohne Aufruf sollte gemäß der ursprünglichen DOS-Spezifikation eine Befehlsverkettung durchgeführt und NICHT zurückgegeben werden. Eine beliebte Option vor dem Hinzufügen von "CALL" war das Öffnen einer untergeordneten Eingabeaufforderung wie "command / c second.bat", da diese ebenfalls zurückgegeben wird.
Brian Knoblauch
1
Ich hatte das Problem unter Windows 7 entreprise, also ist es nicht nur xp
Rafiki
5
Unter Windows 10 wird nur die erste Zeile ausgeführt. Die Antwort von farheen hat jedoch funktioniert.
Robro
2
Übergeben von Parametern an die Batchdateien. Einer der Parameter ist ein Pfad mit Leerzeichen.
Zeus
179

Alle anderen Antworten sind richtig: Anruf verwenden. Zum Beispiel:

 call "msbuild.bat"

Geschichte

In alten DOS-Versionen war es nicht möglich, Batch-Dateien rekursiv auszuführen. Dann wurde der Aufrufbefehl eingeführt, der eine andere cmd-Shell aufrief, um die Batchdatei auszuführen, und die Ausführung nach Abschluss an die aufrufende cmd-Shell zurückgab.

Offensichtlich war in späteren Versionen keine andere cmd-Shell mehr erforderlich.

In den frühen Tagen hingen viele Batchdateien davon ab, dass das Aufrufen einer Batchdatei nicht zur aufrufenden Batchdatei zurückkehren würde. Das Ändern dieses Verhaltens ohne zusätzliche Syntax hätte viele Systeme wie Batch-Menüsysteme (Verwendung von Batch-Dateien für Menüstrukturen) beschädigt.

Wie in vielen Fällen bei Microsoft ist daher die Abwärtskompatibilität der Grund für dieses Verhalten.

Tipps

Wenn Ihre Batchdateien Leerzeichen enthalten, verwenden Sie Anführungszeichen um den Namen:

call "unit tests.bat"

Übrigens: Wenn Sie nicht alle Namen der Batch-Dateien haben, können Sie dies auch verwenden (dies garantiert nicht die korrekte Reihenfolge der Batch-Dateiaufrufe; es folgt der Reihenfolge des Dateisystems):

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

Sie können auch nach einem Anruf auf Fehlerebenen reagieren. Verwenden:

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

einen Fehlerlevel zurückgeben. 0 bedeutet korrekte Ausführung. In der aufrufenden Batch-Datei können Sie mit reagieren

if errorlevel neq 0 <batch command>

Verwenden if errorlevel 1Sie diese Option, wenn Sie ein älteres Windows als NT4 / 2000 / XP haben, um alle Fehlerstufen 1 und höher abzufangen.

Um den Fluss einer Batch-Datei zu steuern, gehen Sie zu :-(

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

Wie andere betonten: Schauen Sie sich Build-Systeme an, um Batch-Dateien zu ersetzen.

Ralph M. Rickenbach
quelle
vereinbart, aber die Schleife könnte in diesem Fall die Dateien in der falschen (alphabetischen?) Reihenfolge verarbeiten
Dave Archer
Schöne und sehr vollständige Antwort. Wenn Sie den Kontrollfluss einschließen, sollten Sie beachten, dass Sie anstelle von goto Unterroutinen mit call: label1 ausführen können und die Anweisung 'return' in Batch-Dateien das etwas seltsame goto: eof ist (und nicht erforderlich ist) Erstellen Sie selbst ein Eof-Label (das standardmäßig vorhanden ist).
Legolas
Das errorlevelBefehlsbeispiel gab mir ein Problem unter Windows 10 (in der Cmd-Konsole). Ich habe den Befehl einfach so geändert, dass er ist if errorlevel neq echo Houston We have a Problem!. Mein Batch-Prozess hatte keine Probleme und wurde größtenteils normal abgeschlossen, aber bei jedem Schritt, bei dem ich diesen Befehl nach einer Aufrufanweisung verwendet habe, wurde "neq war zu diesem Zeitpunkt unerwartet" angezeigt. Da ich dachte, dass sie möglicherweise die ungleiche Syntax geändert haben, habe ich es versucht !=und auch <>immer wieder den gleichen Fehler "zu diesem Zeitpunkt nicht erwartet" für die neue Syntax erhalten. Was könnte ich falsch machen?
TMWP
117

Wenn wir mehrere Eingabeaufforderungen öffnen möchten, können wir verwenden

start cmd /k

/k: ist obligatorisch und wird ausgeführt.

Das Starten vieler Befehlsansagen kann wie folgt erfolgen.

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
quelle
7
das ist, wonach wir gesucht haben, als unsere erste App die Konsole blockiert, danke für den Hinweis
Michael Moeller
1
Dadurch werden mehrere Befehlsinstanzen ausgeführt und sogar mehrere Batchdateien mit <pause> ausgeführt. +1, da dies genau die Lösung ist, nach der ich gesucht habe!
Christian Noel
5
Könnten Sie bitte erklären, dass diese Zahlen in Ihrer Antwort enthalten sind? Ihr Zweck ist nicht klar.
Kalamalka Kid
2
Beachten Sie, dass die meisten Benutzer wahrscheinlich verwenden möchten, start "Window title" /wait cmd /k call something.batum Dinge in sequentieller Reihenfolge auszuführen.
Andrew
2
(oder start "Window title" /wait cmd /c something.bat, wo cmd /cdas Fenster schließt, wenn es fertig ist)
Andrew
42

Versuchen:

call msbuild.bat
call unit-tests.bat
call deploy.bat
Jonathan
quelle
28

Sie rufen mehrere Stapel auf, um ein Programm zu kompilieren. Ich
gehe davon aus, dass im Fehlerfall: 1) Das Programm innerhalb des Stapels mit einer Fehlerstufe beendet wird;
2) Sie möchten es wissen.

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

'||' testet auf eine Fehlerstufe höher als 0. Auf diese Weise werden alle Stapel der Reihe nach aufgerufen, werden jedoch bei jedem Fehler angehalten, sodass der Bildschirm so bleibt, wie Sie eine Fehlermeldung sehen.

Jay
quelle
23

Wenn wir zwei Batch-Skripte haben, aaa.bat und bbb.bat, und wie unten aufrufen

call aaa.bat
call bbb.bat

Wenn Sie das Skript ausführen, ruft es zuerst aaa.bat auf, wartet, bis der Thread von aaa.bat beendet ist, und ruft bbb.bat auf.

Wenn Sie jedoch nicht warten möchten, bis aaa.bat beendet wird, um bbb.bat aufzurufen, verwenden Sie den Befehl START :

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

Prüfung:

start /b aaa.bat
start /b bbb.bat
user2314621
quelle
22
call msbuild.bat
call unit-tests.bat
call deploy.bat
Butterhuhn
quelle
20

Verwenden Sie zum Aufrufen einer .batDatei innerhalb einer .batDatei

call foo.bat

(Ja, das ist albern, es wäre sinnvoller, wenn Sie es mit aufrufen könnten foo.bat, wie Sie es an der Eingabeaufforderung tun könnten, aber der richtige Weg ist, es zu verwenden call.)

Zifre
quelle
7

Haben Sie bei der Betrachtung Ihrer Dateinamen in Betracht gezogen, ein Build-Tool wie NAnt oder Ant (die Java-Version) zu verwenden ? Sie erhalten viel mehr Kontrolle als mit Fledermausdateien.

Dave Archer
quelle
7

Wenn Sie viele Batchdateien gleichzeitig öffnen möchten, können Sie den Befehl call verwenden. Der Aufrufbefehl schließt jedoch die aktuelle Bat-Datei und wechselt zu einer anderen. Wenn Sie viele gleichzeitig öffnen möchten, können Sie Folgendes versuchen:

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

Und so weiter oder wiederholen Sie den Start cmd" call..." für so viele Dateien. Dies funktioniert unter Windows 7 , bei anderen Systemen bin ich mir jedoch nicht sicher.

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

Wenn das nicht funktioniert, ersetzen Sie es startdurch calloder versuchen Sie Folgendes:

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

Verwenden Sie einfach den callBefehl! Hier ist ein Beispiel:

call msbuild.bat
call unit-tests.bat
call deploy.bat
PryroTech
quelle
3

Bei korrekter Angabe (dies kann manchmal schwierig sein):

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

1. arg - Titel (in diesem Fall leer)
2. arg - / D gibt das Startverzeichnis an, kann weggelassen werden, wenn das aktuelle Arbeitsverzeichnis (z. B. "% ~ dp0")
3. arg - Befehl "cmd.exe"
4 gestartet werden soll arg - zu befehlende Argumente mit doppelten Anführungszeichen für die darin enthaltenen Argumente (so entziehen Sie Anführungszeichen in Anführungszeichen im Stapel)

robertcollier4
quelle
2

Beim Ausführen mehrerer Skripte in einem hatte ich das gleiche Problem. Ich ließ es beim ersten Mal sterben, ohne zu bemerken, dass es beim ersten Drehbuch beendet wurde.

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

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

Ich entfernte alle 11 EXIT-Zeilen meiner Skripte und versuchte es erneut. Alle 11 wurden nacheinander im selben Befehlsfenster ausgeführt.

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

::ScriptA.bat
Do Foo

::ScriptB.bat
Do bar
John Oliphant
quelle
Entfernen Sie die exits nicht, goto :eofsondern ersetzen Sie sie stattdessen durch. Dies wird zumcall
Stephan
Sie erkennen, dass in einem einfachen Stapel Befehle in der Reihenfolge ausgeführt werden, in der sie auch als Grundlayout für Indizes bezeichnet werden. @echo off :menu some commands goto menuBeachten Sie, dass dies eine Endlosschleife ausführt, bis es geschlossen wird. Im Grunde brauchen Sie nicht die ::nur:
CMS_95
0

Folgendes löste mein Problem:

start call "batch1.bat"
start call "batch2.bat"
Quinn
quelle
0

Vielleicht möchten Sie das:

Führen Sie die Batch-Skripte parallel aus.

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

Hier werden drei Batchdateien in minimierten Befehlsfenstern im minimierten Zustand ausgeführt. Wenn Sie nicht möchten, dass sie minimiert werden, entfernen Sie sie /min. Wenn Sie sie später nicht mehr steuern müssen, können Sie die Titel auch entfernen. Es wird also ein Bare-Bone-Befehl ausgeführtstart cmd /k call systemLogCollector.bat


Wenn Sie sie beenden möchten-

taskkill /FI "WindowTitle eq appLogCollector*" /T /F
taskkill /FI "WindowTitle eq uiLogCollector*" /T /F
taskkill /FI "WindowTitle eq systemLogCollector*" /T /F
Minhas Kamal
quelle