web-dev-qa-db-fra.com

Pour «appeler» ou «ne pas appeler» un fichier batch?

Si, à l'intérieur d'un fichier de chauve-souris, vous avez appelé un autre fichier de commandes mais qu'il vous restait encore quelques opérations à terminer, comment pouvez-vous vous assurer que l'appel au premier fichier de chauves-souris, après achèvement ou erreur, reviendra au fichier qui l'a appelé dans le premier exemple?

Exemple:

CD:\MyFolder\MyFiles
Mybatfile.bat

Copy afile toHere

ou

CD:\MyFolder\MyFiles
CALL Mybatfile.bat

COPY afile toHere

Quelle est la différence entre l'utilisation de CALL ou START ou aucune d'entre elles? Est-ce que cela aurait un impact sur le retour des résultats de la commande de copie ou non?

48
AltF4_

Comme d'autres l'ont dit, CALL est le moyen normal d'appeler un autre fichier bat dans un .bat et de revenir à l'appelant.

Cependant, tout traitement de fichiers batch cessera (le contrôle ne reviendra pas à l'appelant) si le fichier batch CALLed a une erreur de syntaxe fatale, ou si le script CALLed se termine avec EXIT sans l'option/B.

Vous pouvez garantir que le contrôle reviendra à l'appelant (tant que la fenêtre de la console reste bien sûr ouverte) si vous exécutez le 2ème script via la commande CMD.

cmd /c "calledFile.bat"

Mais cela a une limitation: les variables d'environnement définies par le lot appelé ne seront pas conservées lors du retour.

Je ne connais pas de bonne solution pour garantir le retour dans tous les cas et préserver les changements d'environnement.

Si vous avez vraiment besoin de conserver des variables lors de l'utilisation de CMD, vous pouvez demander au script "appelé" d'écrire les modifications des variables dans un fichier temporaire, puis demander à l'appelant de lire le fichier temporaire et de rétablir les variables.

55
dbenham

call est nécessaire pour les fichiers .bat ou .cmd, sinon le contrôle ne reviendra pas à l'appelant.
Pour les fichiers exe, ce n'est pas obligatoire.

Start n'est pas la même chose que call, il crée une nouvelle instance de cmd.exe, il peut donc exécuter un fichier de commandes appelé asynchronosly

32
jeb

L'instruction `CALL 'a été introduite dans MS-DOS 3.3

Il est utilisé pour appeler d'autres fichiers de commandes dans un fichier de commandes, sans interrompre l'exécution du fichier de commandes appelant et en utilisant le même environnement pour les deux fichiers de commandes.

Donc, dans votre cas, la solution consiste à utiliser CALL

10
Saju

D'accord, je n'ai même pas vraiment pensé au fait que si vous appelez un lot (quel que soit le "type", c'est-à-dire ".bat" ou ".cmd"), il ne reviendra pas si vous ne le faites pas utiliser l'appel.

J'utilise call moi-même pour une raison différente, je suis en fait assez surpris que personne d'autre n'ait parlé. Peut-être que je l'ai raté. PEUT-ÊTRE JE SUIS LE SEUL AU MONDE À SAVOIR !! : O

Probablement pas, mais je vais déposer cette connaissance ici parce que c'est super utile.

Si vous utilisez l'appel, vous pouvez utiliser des opérateurs de logique binaire pour décider comment procéder en fonction du résultat ERRORLEVEL. En fait, j'ai toujours été sidéré par la façon dont && et || existait sous DOS et ne pouvait pas être utilisé de cette façon. Voilà pourquoi.

La façon la plus simple de tester cela est de créer un return.cmd Avec le bloc-notes, ou à partir de l'invite de commande comme ceci:

c:\> type con >return.cmd       

Vous remarquerez maintenant que le curseur descend jusqu'à la ligne suivante et se bloque. Entrer:

@exit /B %1

Et puis appuyez sur [ENTER], puis sur [CTRL] - [Z] et ce fichier sera créé. Bien! Vous pouvez maintenant vous sentir libre d'essayer les deux exemples suivants:

call return.cmd 0 && echo Huzzah! A Complete Success! (Or cover up...)

call return.cmd 123 || echo Oops! Something happened. You can check ERRORLEVEL if you want the tinest amount of additional information possible.

Et alors? Eh bien, exécutez-les à nouveau avec le 0 et le 123 échangés et vous devriez voir que les messages NE S'IMPRIMENT PAS.

Peut-être que cet exemple multi-lignes aura plus de sens. Je l'utilise tout le temps:

     call return.cmd 0 && @(
         echo Batch says it completed successfully^^!
     ) || @(
         echo Batch completed, but returned a 'falsey' value of sort.
         call echo The specific value returned was: %ERRORLEVEL%
     )     

(Notez "l'appel" dans la section || Avant le deuxième "écho". Je pense que c'est ainsi que les gens se sont déplacés sans retarder l'expansion dans la journée. Si vous avez activé l'expansion retardée (via. Setlocal EnableDelayedExpansion à l'intérieur d'un lot OR lancez une invite de commande avec cmd /v:on Alors vous pouvez le faire! ERRORLEVEL !.)

... C'est là que je dois m'excuser et dire que si vous avez if ERRORLEVEL Un traumatisme dans votre passé, vous devriez arrêter de lire. J'ai compris. Croyez-moi. J'ai pensé à payer quelqu'un sur fiverr pour taper ceci à distance pour moi, mais par souci d'exhaustivité, je vais juste en prendre un pour l'équipe et mentionner que vous pouvez également faire ce qui suit pour vérifier le niveau d'erreur:

    if ERRORLEVEL 123 @echo QUICK! MOTHERS, COVER YOUR CHILDREN'S EYES! FINGERS ARE BEING UNDONE! :'(

Si vous n'avez jamais tapé cela auparavant, alors BON! Vous vivrez plus longtemps sans avoir à lire pourquoi vous n'obtenez pas exactement les résultats escomptés. Cruel est le mot que vous recherchez, pas "excentrique".


Cependant, la partie importante que je veux vraiment faire passer est que si vous essayez ceci et N'UTILISEZ PAS 'call' cela exécutera TOUJOURS la branche 'true'. Essayez-le vous-même!

Si je manque quelque chose ou si vous connaissez une meilleure façon de procéder, faites-le moi savoir. J'adore apprendre des trucs comme ça!


Informations supplémentaires que j'ai mentionnées:

Je sais depuis un certain temps que vous pouvez mettre des redirections AVANT des commandes comme ceci:

    >nul echo. This won't be displayed!

Mais j'ai accidentellement découvert l'autre jour en étant un idiot que vous pouvez apparemment aussi faire:

    echo A B>file.txt C

Et j'ai été VRAIMENT surpris de trouver un file.txt Composé de "A B C". Il semble que vous puissiez les placer N'IMPORTE O, même à l'intérieur de la commande. Je n'ai jamais vu personne faire cela, ni le mentionner, mais j'ai vu des gens mentionner que vous pouvez préfixer une ligne avec eux.

C'est peut-être un bogue exclusif à Windows 10 ou quelque chose. Si vous avez une autre version et que vous voulez l'essayer et faites-moi savoir que je serais intéressé par ce que vous découvrirez.

Restez ringard!

1
Brent Rittenhouse