web-dev-qa-db-fra.com

Comment puis-je activer/désactiver @ECHO de manière conditionnelle dans un fichier batch Windows?

J'ai un fichier batch qui peut être exécuté localement ou sur le serveur de compilation pour effectuer un travail intéressant. Sur l'ordinateur local, je veux @ECHO OFF afin que votre console ne soit pas pleine de chaînes de débogage. Sur le serveur de compilation, je préférerais avoir @ECHO ON afin que les défaillances puissent être examinées.

Le contexte du serveur de génération peut être déterminé si une variable d’environnement spéciale existe (TEAMCITY_PROJECT_NAME). Alors, je pensais pouvoir faire quelque chose comme

IF DEFINED TEAMCITY_PROJECT_NAME @ECHO ON ELSE @ECHO OFF

Mais, cela ne fonctionne pas, la déclaration IF s'affiche avec tout le reste ... des pensées?

9
Anthony Mastrean

La commande n'est pas nommée @echo. Le @ est un drapeau facultatif valide au début d'une instruction pour indiquer que l'écho est supprimé pour cette instruction. Donc, utiliser le @ sur chaque référence à la commande echo masquera la commande echo elle-même, mais pas la commande if qui la précède. 

Mais le problème qui fait en sorte que votre commande ne fonctionne pas comme prévu est que la première commande echo éclaire le reste des jetons de la ligne en tant qu'arguments, de sorte que la partie else echo off ne sera pas interprétée par CMD. Etant donné que CMD.EXE renvoie par défaut, il imprime la commande if, puis exécute une seule commande echo ou rien. Puisque le @ a une signification au début de l'instruction qui est le corps de la if, aucune commande echo ne sera imprimée.

En général, la solution consiste à utiliser des parenthèses pour délimiter les limites des commandes. Cependant, étant donné que echo est activé par défaut et que vous ne voulez vraiment le supprimer que si TEAMCITY_PROJECT n'est pas défini, nous pouvons le dire directement.

@IF NOT DEFINED TEAMCITY_PROJECT_NAME ECHO OFF

J'ai laissé un seul @ au début pour supprimer l'écho de cette ligne. Cette ligne n'apparaîtra donc pas dans les journaux de votre serveur.

Note connexe

L'état d'écho s'applique également à une session interactive. Si vous saisissez echo off lors d'une invite de session interactive CMD, il cessera d'afficher l'invite. Ce qui est un peu déconcertant, sinon inattendu. Taper echo on restaure le comportement normal.

Plus sur l'analyse

(J'ai modifié la section précédente pour plus de clarté et ajouté cette section pour tenter de documenter ce qui se passe réellement.)

Le programme CMD.EXE qui interprète les scripts .BAT et .CMD et fournit la commande interactive Invite dans Windows moderne est étonnamment bien documenté sans être documenté. Mes tentatives pour rechercher un document officiel expliquant que le signe at a cet effet et où il peut être utilisé ont été en grande partie infructueuses.

Les expériences ont clairement montré que le signe at est analysé et interprété s'il apparaît comme le premier caractère non blanc d'une commande. J'ai essayé de l'exprimer en utilisant l'expression "début d'une déclaration" ci-dessus. 

Autant que je sache, il n'y a pas de grammaire formelle publiée pour le langage de CMD. Cependant, la documentation de CDM elle-même (type cmd /? dans une invite), ainsi que if /? et le texte d'aide intégré d'autres commandes intégrées "intéressantes", indique que certaines règles sont suivies lorsque CMD analyse son texte source. .

Le début d'une commande semble se situer au début d'une ligne ou après la condition if, après la else ou après une parenthèse ouverte (. Une fois que l'ar-signe a été reconnu, il s'applique à (la plupart) du solde de cette commande.

Essayez vous-même le fichier de commandes suivant et jouez avec le déplacement des signes at et vous aurez rapidement l’impression que les règles sont difficiles à énoncer avec précision:

rem this remark will echo
@rem this one will not
@ rem neither will this
 @rem nor this one
@rem the if command (and else) will echo, but not either echo command
if exist q17241089.bat ( @ echo saw q17241089.bat ) else @ echo foo
if not exist q17241089.bat ( @ echo no q17241089.bat ) else @ echo bar
@ rem none of the following command is echoed
@ if exist q17241089.bat ( @ echo saw q17241089.bat ) else @ echo spam

Lorsqu'il est exécuté sur mon Win 7 Pro, je vois:

C...>
C...>q17241089.bat

C...>rem this remark will echo

C...>if exist q17241089.bat ()  else
saw q17241089.bat

C...>if not exist q17241089.bat ()  else
bar
saw q17241089.bat
C...>

Comme avec la plupart des détails des fichiers BAT, il existe un mystère sous chaque surface que vous grattez.

15
RBerteig

entre parenthèses (voir docu ...):

IF DEFINED TEAMCITY_PROJECT_NAME (@ECHO ON) ELSE @ECHO OFF
4
Endoro

Eh bien, il semble que ECHO soit activé par défaut, vous obtiendrez la sortie de l'instruction IF de toute façon, vous testerez cette condition. Tu devrais commencer avec

@ECHO OFF

Et ajoutez votre condition comme une autre déclaration à évaluer

@ECHO OFF && IF DEFINED TEAMCITY_PROJECT_NAME @ECHO ON
2
Anthony Mastrean

Comme indiqué dans les réponses précédentes, ECHO est activé par défaut. Une autre façon d'obtenir le même comportement est la suivante:

@if "%TEAMCITY_PROJECT_NAME%" == "" @echo off
1
JoeG