867 Stimmen

Wie man mehrere BAT-Dateien innerhalb einer BAT-Datei ausführt

Ich versuche, meine commit-build.bat um andere .BAT-Dateien als Teil unseres Build-Prozesses auszuführen.

Inhalt der commit-build.bat :

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

Das scheint einfach zu sein, aber commit-build.bat führt nur den ersten Eintrag in der Liste aus ( msbuild.bat ).

Ich habe jede der Dateien einzeln ausgeführt, ohne dass es Probleme gab.

4 Stimmen

@sean - Sie müssen nicht das komplette Cygwin-Paket installieren, um die Kommandozeilenprogramme zum Laufen zu bringen. Nehmen Sie einfach alle Cygwin-Dlls aus dem Paket und legen Sie sie in ein Verzeichnis mit einem Pfad, legen Sie alle Ihre Tools in ein anderes Verzeichnis mit einem Pfad, und Sie sind bereit zu gehen.

0 Stimmen

Wenn man davon ausgeht, dass es sich bei jeder dieser Dateien nur um eine Stapelverarbeitung handelt, warum werden sie nicht einfach in eine große Datei eingefügt und die Timeout-Funktion verwendet, um jedes Mal zu starten.

1456voto

Philippe Leybaert Punkte 161931

Verwendung:

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

Wenn Sie CALL nicht verwenden, wird die aktuelle Batch-Datei angehalten und die aufgerufene Batch-Datei beginnt mit der Ausführung. Dies ist ein merkwürdiges Verhalten, das auf die frühen MS-DOS-Tage zurückgeht.

204voto

Ralph M. Rickenbach Punkte 12431

Alle anderen Antworten sind richtig: verwenden Sie call. Zum Beispiel:

 call "msbuild.bat"

Geschichte

In alten DOS-Versionen war es nicht möglich, Batch-Dateien rekursiv auszuführen. Dann wurde der call-Befehl eingeführt, der eine andere cmd-Shell aufrief, um die Batch-Datei 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 nötig.

In der Anfangszeit waren viele Batchdateien darauf angewiesen, dass der Aufruf einer Batchdatei nicht zur aufrufenden Batchdatei zurückführt. Eine Änderung dieses Verhaltens ohne zusätzliche Syntax hätte viele Systeme wie z. B. Batch-Menüsysteme (die Batch-Dateien für Menüstrukturen verwenden) zerstört.

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

Tipps

Wenn Ihre Batchdateien Leerzeichen im Namen haben, setzen Sie den Namen in Anführungszeichen:

call "unit tests.bat"

Übrigens: Wenn Sie nicht alle Namen der Stapeldateien haben, können Sie auch for verwenden, um dies zu tun (es garantiert nicht die korrekte Reihenfolge der Stapeldateiaufrufe; es folgt der Reihenfolge des Dateisystems):

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

Sie können auch auf Fehlerstufen nach einem Aufruf reagieren. Verwenden:

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

um eine Fehlerstufe zurückzugeben. 0 steht für eine korrekte Ausführung. In der aufrufenden Stapeldatei können Sie reagieren, indem Sie

if errorlevel neq 0 <batch command>

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

Um den Ablauf einer Batch-Datei zu steuern, gibt es goto :-(

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

Wie bereits von anderen erwähnt: Schauen Sie sich Build-Systeme an, die Batch-Dateien ersetzen können.

159voto

farheen Punkte 1656

Wenn wir mehrere Eingabeaufforderungen öffnen wollen, können wir Folgendes verwenden

start cmd /k

/k : ist obligatorisch und wird ausgeführt.

Das Starten vieler Eingabeaufforderungen 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.

44voto

Jonathan Punkte 11561

Versuchen Sie es:

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

34voto

npocmaka Punkte 52753

Mit " & "

Wie Sie bemerkt haben, ist die direkte Ausführung der Fledermaus ohne CALL , START , CMD /C bewirkt, dass die erste Datei eingegeben und ausgeführt wird und dass der Prozess gestoppt wird, sobald die erste Datei beendet ist. Sie können jedoch auch & was dasselbe ist wie die Verwendung von command1 & command2 direkt in der Konsole:

(
    first.bat
)&(
    second.bat
)& (
    third.bat
)&(
    echo other commands
)

Im Hinblick auf die Maschinenressourcen ist dies der effizienteste Weg, obwohl Sie im letzten Block keine Kommandozeile verwenden können GOTO , SHIFT , SETLOCAL und seine Möglichkeiten sind fast die gleichen wie bei der Ausführung von Befehlen in der Eingabeaufforderung. Und nach der letzten schließenden Klammer können Sie keinen weiteren Befehl mehr ausführen

Verwendung von ANRUFEN

call first.bat
call second.bat
call third.bat

In den meisten Fällen wird dies der beste Ansatz sein - es wird kein separater Prozess erstellt, sondern das Verhalten ist fast identisch mit dem Aufruf einer :label als Unterroutine. In der MS-Terminologie wird ein neuer "Batch-Dateikontext" erstellt und die Kontrolle an die Anweisung nach dem angegebenen Label übergeben. Wenn das erste Mal das Ende der Stapeldatei erreicht wird (d.h. nach dem Sprung zum Label), wird die Kontrolle an die Anweisung nach der Aufrufanweisung zurückgegeben."

Sie können Variablen verwenden, die in den aufgerufenen Dateien gesetzt sind (wenn sie nicht in einer SETLOCAL Block), können Sie direkter Zugriff auf Etiketten in der aufgerufenen Datei .

CMD /C Rohre , FOR /F

Andere native Option ist die Verwendung von CMD /C (der Schalter /C zwingt die aufgerufene Konsole, sich zu beenden und die Kontrolle zurückzugeben) Etwas, das cmd.exe auf nicht transparente Weise tut, indem es FOR /F gegen bat-Datei oder bei Verwendung von Pipes. Dadurch wird ein Kindprozess erzeugt, der die gesamte Umgebung der aufrufenden Fledermaus hat. Weniger effizient in Bezug auf die Ressourcen, aber da der Prozess separat ist, kann das Parsen von Abstürzen oder der Aufruf eines EXIT Befehl wird die aufrufende .bat nicht anhalten

@echo off
CMD /c first.bat
CMD /C second.bat

::not so different than the above lines.
:: MORE,FINDSTR,FIND command will be able to read the piped data 
:: passed from the left side

break|third.bat

START

Ermöglicht Ihnen mehr Flexibilität, z. B. die Möglichkeit, die Skripte in einem separaten Fenster zu starten, nicht zu warten, bis sie beendet sind, einen Titel zu setzen usw. Standardmäßig wird das .bat y .cmd Skripte mit CMD /K Das bedeutet, dass die gestarteten Skripte nicht automatisch geschlossen werden, was wiederum die gesamte Umgebung an die gestarteten Skripte weitergibt und mehr Ressourcen verbraucht als cmd /c :

:: will be executed in the same console window and will wait to finish
start "" /b /w cmd /c first.bat 

::will start in a separate console window and WONT wait to be finished
:: the second console window wont close automatically so second.bat might need explicit exit command
start "" second.bat

::Will start it in a separate window ,but will wait to finish
:: closing the second window will cause Y/N prompt
:: in the original window 
start "" /w third.cmd

::will start it in the same console window
:: but wont wait to finish. May lead to a little bit confusing output
start "" /b cmd /c fourth.bat

WMIC

Im Gegensatz zu den anderen Methoden werden die Beispiele von nun an externe CMD.exe-Dienstprogramme verwenden (die unter Windows immer noch standardmäßig verfügbar sind). Das WMIC-Dienstprogramm erstellt einen völlig separaten Prozess, so dass Sie nicht direkt auf die Beendigung warten können. Die beste Eigenschaft von WMIC ist jedoch, dass es die ID des erzeugten Prozesses zurückgibt:

:: will create a separate process with cmd.exe /c
WMIC process call create "%cd%\first.bat","%cd%"

::you can get the PID and monitoring it with other tools
for /f "tokens=2 delims=;= " %%# in ('WMIC process call create "%cd%\second.bat"^,"%cd%" ^|find "ProcessId"') do (
    set "PID=%%#"
)
echo %PID%

Sie können es auch verwenden, um einen Prozess auf einem entfernten Rechner mit einem anderen Benutzer usw. zu starten.

SCHTASKS

Die Verwendung von SCHTASKS bietet einige Funktionen wie (offensichtliche) Zeitplanung, Ausführung als ein anderer Benutzer (sogar als der Systembenutzer), Fernstart von Maschinen und so weiter. Wiederum startet es in einer völlig separaten Umgebung (d.h. mit eigenen Variablen) und sogar als versteckter Prozess, xml-Datei mit Befehlsparametern usw:

SCHTASKS /create /tn BatRunner /tr "%cd%\first.bat" /sc ONCE /sd 01/01/1910 /st 00:00
SCHTASKS /Run /TN BatRunner
SCHTASKS /Delete /TN BatRunner /F

Hier kann die PID auch aus dem Ereignisprotokoll gewonnen werden.

ScriptRunner

Bietet eine gewisse Zeitspanne zwischen gestarteten Skripten. Grundlegende Transaktionsfunktionen (z. B. Rollback bei Fehler) und die Parameter können in einer separaten XML-Datei gespeichert werden.

::if the script is not finished after 15 seconds (i.e. ends with pause) it will be killed
ScriptRunner.exe -appvscript %cd%\first.bat -appvscriptrunnerparameters -wait -timeout=15

::will wait or the first called script before to start the second
:: if any of the scripts exit with errorcode different than 0 will try
:: try to restore the system in the original state
ScriptRunner.exe -appvscript second.cmd arg1 arg2 -appvscriptrunnerparameters -wait -rollbackonerror -appvscript third.bat -appvscriptrunnerparameters -wait -timeout=30 -rollbackonerror

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X