Comment exécuter plusieurs fichiers .BAT dans un fichier .BAT

695

J'essaie d'obtenir mon commit-build.batpour exécuter d'autres fichiers .BAT dans le cadre de notre processus de construction.

Contenu de commit-build.bat:

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

Cela semble assez simple, mais commit-build.batn'exécute que le premier élément de la liste ( msbuild.bat).

J'ai exécuté chacun des fichiers séparément sans aucun problème.

Yvette
la source
4
@sean - Vous n'avez pas besoin d'installer le package Cygwin complet pour que les utilitaires de ligne de commande fonctionnent. Retirez simplement toutes les DLL cygwin du package, placez-les dans un répertoire avec chemin, placez tous vos outils dans un autre répertoire avec chemin et c'est parti.
Techie Joe
en supposant que chacun de ces fichiers ne soit que par lot, pourquoi ne pas simplement les mettre dans un grand fichier et utiliser la fonction de délai d'attente pour permettre à chaque fois de démarrer.
CMS_95

Réponses:

1200

Utilisation:

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

Lorsque vous n'utilisez pas CALL, le fichier de commandes en cours s'arrête et le fichier de commandes appelé commence à s'exécuter. C'est un comportement particulier qui remonte aux premiers jours de MS-DOS.

Philippe Leybaert
la source
bizarre, j'ai essayé sans "appeler" sur windows 7 et je me souviens que cela fonctionnait, mais sur windows xp il fallait cette commande. est-ce que ça pourrait être?
développeur Android
7
Sans appel, selon la spécification DOS d'origine, devrait faire le chaînage des commandes et NE PAS retourner. Une option populaire avant l'ajout de "CALL" consistait à ouvrir une invite de commande enfant comme "command / c second.bat" car cela reviendrait également.
Brian Knoblauch
1
J'ai eu le problème sur Windows 7 entreprise donc ce n'est pas seulement xp
Rafiki
5
Sur Windows 10, seule la première ligne est exécutée. La réponse de farheen a cependant fonctionné.
robro
2
Comment passer des paramètres aux fichiers batch, et l'un des paramètres est un chemin avec des espaces.
Zeus
179

Toutes les autres réponses sont correctes: utilisez l'appel. Par exemple:

 call "msbuild.bat"

Histoire

Dans les anciennes versions DOS, il n'était pas possible d'exécuter récursivement des fichiers batch. Ensuite, la commande d'appel a été introduite qui a appelé un autre shell cmd pour exécuter le fichier de commandes et renvoyé l'exécution au shell cmd appelant une fois terminé.

Évidemment, dans les versions ultérieures, aucun autre shell cmd n'était plus nécessaire.

Au début, de nombreux fichiers de commandes dépendaient du fait que l'appel d'un fichier de commandes ne reviendrait pas au fichier de commandes appelant. Changer ce comportement sans syntaxe supplémentaire aurait brisé de nombreux systèmes comme les systèmes de menus par lots (en utilisant des fichiers de commandes pour les structures de menus).

Comme dans de nombreux cas avec Microsoft, la compatibilité descendante est donc la raison de ce comportement.

Conseils

Si vos fichiers batch ont des espaces dans leurs noms, utilisez des guillemets autour du nom:

call "unit tests.bat"

Soit dit en passant: si vous n'avez pas tous les noms des fichiers de commandes, vous pouvez également utiliser for pour cela (cela ne garantit pas l'ordre correct des appels de fichiers de commandes; il suit l'ordre du système de fichiers):

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

Vous pouvez également réagir sur les niveaux d'erreur après un appel. Utilisation:

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

pour redonner un niveau d'erreur. 0 indique une exécution correcte. Dans le fichier batch appelant, vous pouvez réagir en utilisant

if errorlevel neq 0 <batch command>

À utiliser if errorlevel 1si vous avez un Windows plus ancien que NT4 / 2000 / XP pour intercepter tous les niveaux d'erreur 1 et supérieurs.

Pour contrôler le flux d'un fichier batch, il y a goto :-(

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

Comme d'autres l'ont souligné: jetez un œil aux systèmes de construction pour remplacer les fichiers batch.

Ralph M. Rickenbach
la source
d'accord, mais la boucle pourrait, dans ce cas, traiter les fichiers dans le mauvais ordre (alphabétique?)
Dave Archer
Réponse agréable et très complète. Si vous incluez le flux de contrôle, il peut être bon de noter qu'au lieu de goto, vous pouvez faire des sous-routines en utilisant call: label1, et l'instruction 'return' dans les fichiers batch est le goto: eof légèrement étrange (et pas besoin de faites vous-même une étiquette eof, qui existe par défaut).
Legolas
l' errorlevelexemple de commande m'a donné un problème sur Windows 10 (dans la console cmd). J'ai simplement modifié la commande pour être if errorlevel neq echo Houston We have a Problem!. Mon processus par lots n'a eu aucun problème et s'est terminé normalement, mais à chaque étape de la façon dont j'ai utilisé cette commande après une instruction d'appel, j'ai obtenu "neq était inattendu à ce moment". Pensant qu'ils ont peut-être changé la syntaxe non égale, j'ai essayé !=et j'ai <>continué à obtenir la même erreur "inattendue à ce moment" pour la nouvelle syntaxe. que pourrais-je faire de mal?
TMWP
117

Si nous voulons ouvrir plusieurs invites de commande, nous pouvons utiliser

start cmd /k

/k: est obligatoire qui s'exécutera.

Le lancement de nombreuses invites de commande peut être effectué comme ci-dessous.

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
la source
7
c'est ce que nous recherchions, car notre première application bloque la console, merci pour l'astuce
Michael Moeller
1
cela exécutera plusieurs instances de commande et fonctionnera même pour exécuter plusieurs fichiers batch qui ont <pause>. +1 car c'est exactement la solution que je cherchais!
Christian Noel
5
pourriez-vous expliquer que ces chiffres figurent dans votre réponse? Leur objectif n'est pas clair.
Kalamalka Kid
3
Notez que la plupart des gens veulent probablement utiliser start "Window title" /wait cmd /k call something.batpour exécuter les choses dans un ordre séquentiel.
Andrew
3
(ou start "Window title" /wait cmd /c something.bat, où cmd /cferme la fenêtre une fois terminée)
Andrew
42

Essayer:

call msbuild.bat
call unit-tests.bat
call deploy.bat
Jonathan
la source
28

Vous appelez plusieurs lots dans le but de compiler un programme. Je tiens pour acquis que si une erreur se produit:
1) Le programme dans le lot se terminera avec un niveau d'erreur;
2) Vous voulez en savoir plus.

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

«||» teste un niveau d'erreur supérieur à 0. De cette façon, tous les lots sont appelés dans l'ordre mais s'arrêtent à toute erreur, laissant l'écran tel qu'il vous permet de voir tout message d'erreur.

Geai
la source
23

Si nous avons deux scripts batch, aaa.bat et bbb.bat, et appelons comme ci-dessous

call aaa.bat
call bbb.bat

Lors de l'exécution du script, il appellera d'abord aaa.bat, attendra la fin du thread de aaa.bat et appellera bbb.bat.

Mais si vous ne voulez pas attendre que aaa.bat se termine pour appeler bbb.bat, essayez d'utiliser la commande START :

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

Examen:

start /b aaa.bat
start /b bbb.bat
user2314621
la source
22
call msbuild.bat
call unit-tests.bat
call deploy.bat
poulet au beurre
la source
20

Pour appeler un .batfichier dans un .batfichier, utilisez

call foo.bat

(Oui, c'est idiot, cela aurait plus de sens si vous pouviez l'appeler avec foo.bat, comme vous le pourriez à partir de l'invite de commande, mais la bonne façon est de l'utiliser call.)

Zifre
la source
7

En regardant vos noms de fichiers, avez-vous envisagé d'utiliser un outil de construction comme NAnt ou Ant (la version Java). Vous aurez beaucoup plus de contrôle qu'avec les fichiers bat.

Dave Archer
la source
7

Si vous souhaitez ouvrir plusieurs fichiers batch simultanément, vous pouvez utiliser la commande call. Cependant, la commande d'appel ferme le fichier bat en cours et passe à un autre. Si vous souhaitez en ouvrir plusieurs à la fois, vous pouvez essayer ceci:

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

Et ainsi de suite ou répétez le démarrage cmd" call..." pour autant de fichiers. Cela fonctionne pour Windows 7 , mais je ne suis pas sûr des autres systèmes.

CMS_95
la source
6
Start msbuild.bat
Start unit-tests.bat
Start deploy.bat

Si cela ne fonctionne pas, remplacez startpar callou essayez ceci:

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

Utilisez simplement la callcommande! Voici un exemple:

call msbuild.bat
call unit-tests.bat
call deploy.bat
PryroTech
la source
3

Avec des citations correctes (cela peut parfois être délicat):

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

1er argument - Titre (vide dans ce cas)
2ème argument - / D spécifie le répertoire de départ, peut être omis si vous voulez que le répertoire de travail actuel (comme "% ~ dp0")
3ème argument - commande à lancer, "cmd.exe"
4ème arg - arguments à commander, avec des guillemets doublés pour les arguments qu'il contient (c'est ainsi que vous échappez les guillemets dans les guillemets en lot)

robertcollier4
la source
2

Exécuter plusieurs scripts en un, j'ai eu le même problème. Je n'arrêtais pas de le faire mourir sur le premier sans me rendre compte qu'il sortait sur le premier script.

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

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

J'ai supprimé les 11 lignes de sortie de mes scripts et j'ai réessayé et les 11 ont été exécutés un par un dans la même fenêtre de commande.

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

::ScriptA.bat
Do Foo

::ScriptB.bat
Do bar
John Oliphant
la source
ne supprimez pas les exits, remplacez-les par à la goto :eofplace. Cela "reviendra" aucall
Stephan
vous vous rendez compte que dans un lot simple, les commandes s'exécuteront dans l'ordre où elles sont appelées également la disposition de base pour les index @echo off :menu some commands goto menu. Fondamentalement, vous n'avez pas besoin du ::juste:
CMS_95
0

Ce qui suit a résolu mon problème:

start call "batch1.bat"
start call "batch2.bat"
Quinn
la source
0

Peut-être voulez-vous ceci:

Exécutez les scripts batch en parallèle

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

Ici, trois fichiers de commandes sont exécutés sur des fenêtres de commande distinctes dans un état réduit. Si vous ne souhaitez pas les réduire, supprimez-les /min. De plus, si vous n'avez pas besoin de les contrôler plus tard, vous pouvez vous débarrasser des titres. Ainsi, une commande à nu serastart cmd /k call systemLogCollector.bat


Si vous souhaitez y mettre fin-

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