J'essaie d'obtenir que mon commit-build.bat
exécute 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.bat
exécute uniquement le premier élément de la liste (msbuild.bat
).
J'ai couru chacun des fichiers séparément sans aucun problème.
Utilisation:
call msbuild.bat
call unit-tests.bat
call deploy.bat
Lorsque vous n'utilisez pas CALL, le fichier de commandes actuel s'arrête et le fichier de commandes appelé commence à s'exécuter. C'est un comportement particulier remontant aux premiers jours de MS-DOS.
Toutes les autres réponses sont correctes: utilisez appel. Par exemple:
call "msbuild.bat"
Histoire
Dans les anciennes versions de DOS, il n'était pas possible d'exécuter de manière récursive des fichiers de commandes. La commande call a ensuite été introduite. Elle a appelé un autre shell cmd pour exécuter le fichier de traitement par lots et a renvoyé l'exécution au shell cmd appelant une fois l'opération terminée.
Évidemment, dans les versions ultérieures, aucun autre cmd Shell n'était 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 dans le fichier de commandes appelant. La modification de ce comportement sans syntaxe supplémentaire aurait endommagé de nombreux systèmes, tels que les systèmes de menu par lots (utilisant des fichiers de traitement par lots pour les structures de menus).
Comme dans de nombreux cas avec Microsoft, la compatibilité ascendante est donc la raison de ce comportement.
Conseils
Si vos noms de fichiers batch contiennent des espaces, utilisez des guillemets autour du nom:
call "unit tests.bat"
Soit dit en passant: si vous ne connaissez pas tous les noms des fichiers de commandes, vous pouvez également utiliser cette option (cela ne garantit pas le bon ordre 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 aux niveaux d'erreur après un appel. Utilisation:
exit /B 1 # Or any other integer value in 0..255
redonner un niveau d'erreur. 0 indique une exécution correcte. Dans le fichier de commandes appelant, vous pouvez réagir en utilisant
if errorlevel neq 0 <batch command>
Utilisez if errorlevel 1
si vous utilisez une version de Windows plus ancienne que NT4/2000/XP pour intercepter tous les niveaux d'erreur 1 et plus.
Pour contrôler le flux d'un fichier de commandes, il faut goto :-(
if errorlevel 2 goto label2
if errorlevel 1 goto label1
...
:label1
...
:label2
...
Comme d'autres l'ont fait remarquer: examinez les systèmes de construction pour remplacer les fichiers de commandes.
Si nous voulons ouvrir plusieurs invites de commande, nous pourrions utiliser
start cmd /k
/k
: est obligatoire pour pouvoir s'exécuter.
Vous pouvez lancer plusieurs invites de commande comme indiqué 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.
Essayer:
call msbuild.bat
call unit-tests.bat
call deploy.bat
Vous appelez plusieurs lots dans le but de compiler un programme. Je prends pour acquis que si une erreur survient:
1) Le programme du lot se termine avec un niveau d'erreur;
2) Vous voulez savoir à ce sujet.
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 manière, tous les lots sont appelés dans l'ordre mais s'arrêteront à toute erreur, laissant l'écran tel quel pour vous permettre de voir le message d'erreur.
call msbuild.bat
call unit-tests.bat
call deploy.bat
Pour appeler un fichier .bat
dans un fichier .bat
, utilisez
call foo.bat
(Oui, c'est idiot, cela aurait plus de sens si vous pouviez l'appeler avec foo.bat
, comme vous le feriez avec l'invite de commande, mais la méthode correcte consiste à utiliser call
.)
Si nous avons deux scripts batch, aaa.bat et bbb.bat, et que nous appelons comme ci-dessous
call aaa.bat
call bbb.bat
Lors de l'exécution du script, il appelle d'abord aaa.bat, attend la fin du thread de aaa.bat et appelle 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
En regardant vos noms de fichiers, avez-vous envisagé d'utiliser un outil de construction tel que NAnt ou Ant (la version Java). Vous aurez beaucoup plus de contrôle qu'avec les fichiers bat.
Start msbuild.bat
Start unit-tests.bat
Start deploy.bat
Si cela ne fonctionne pas, remplacez start
par call
ou essayez ceci:
Start msbuild.bat
Goto :1
:1
Start unit-tests.bat
Goto :2
:2
Start deploy.bat
Si vous souhaitez ouvrir plusieurs fichiers de commandes simultanément, vous pouvez utiliser la commande call. Cependant, la commande call ferme le fichier bat en cours et passe à un autre. Si vous voulez en ouvrir plusieurs à la fois, essayez ceci:
@echo off
start cmd "call ex1.bat&ex2.bat&ex3.bat"
Et ainsi de suite ou recommencez cmd
"call
..." quel que soit le nombre de fichiers. Cela fonctionne pour Windows 7, mais je ne suis pas sûr des autres systèmes.
En exécutant plusieurs scripts en un, j'ai eu le même problème. Je n'arrêtais pas de le faire mourir le premier sans me rendre compte qu'il sortait du 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 EXIT de mes scripts, puis réessayé. Toutes les 11 lignes ont été exécutées dans l'ordre, l'une après l'autre, 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
Utilisez simplement la commande call
! Voici un exemple:
call msbuild.bat
call unit-tests.bat
call deploy.bat
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)
2nd arg -/D spécifie le répertoire de départ, peut être omis si vous voulez le répertoire de travail actuel (tel que "% ~ dp0")
3rd arg - commande de lancement, "cmd.exe"
4th arg - arguments à command, avec des guillemets doubles pour les arguments qu’il contient (c’est ainsi que vous échappez des guillemets entre guillemets dans un lot)
Voici ma voie =
cmd /c ""Path_Bat_Here.bat" %ARG%"
:: Or =
Call *.bat
Aide = cmd /?