ローカルまたはビルドサーバーで実行して、ある種の興味深い仕事を行うことができるバッチファイルがあります。ローカルマシンでは、@ECHO OFF
を使用して、コンソールがデバッグ文字列でいっぱいにならないようにします。ビルドサーバーでは、失敗を調査できるように@ECHO ON
を使用したいと思います。
ビルドサーバーコンテキストは、特別な環境変数(TEAMCITY_PROJECT_NAME
)が存在するかどうかを判断できます。だから、私は次のようなことができると思いました
IF DEFINED TEAMCITY_PROJECT_NAME @ECHO ON ELSE @ECHO OFF
しかし、それは機能していません。IF
ステートメントが他のすべてと一緒にエコーされます...何か考えはありますか?
コマンドの名前は実際には@echo
ではありません。 @
は、ステートメントの先頭で有効なオプションのフラグであり、そのステートメントでエコーが抑制されていることを示します。したがって、echo
コマンドへの各参照で@
を使用すると、echo
コマンド自体は非表示になりますが、その前にあるif
コマンドは非表示になりません。
しかし、実際にコマンドが期待どおりに動作しない原因となっている問題は、最初のecho
コマンドが引数として行の残りのトークンを丸呑みするため、else echo off
部分がCMD
によって解釈されません。 CMD.EXEはデフォルトでエコーするため、if
コマンドを出力し、単一のecho
コマンドを実行するか、何も実行しません。 @
は、if
の本体であるステートメントの先頭で意味を持っているため、どちらのエコーコマンドも出力されません。
一般に、これに対する解決策は、括弧を使用してコマンド境界を区切ることです。ただし、エコーはデフォルトでオンになっており、TEAMCITY_PROJECT
が定義されていない場合にのみエコーを抑制したいので、直接言うことができます。
@IF NOT DEFINED TEAMCITY_PROJECT_NAME ECHO OFF
この行のエコーを抑制するために、最初に@
を1つ残しました。その結果、この行はサーバーのログに表示されません。
エコー状態はインタラクティブセッションにも適用されます。インタラクティブなCMD
セッションプロンプトでecho off
と入力すると、プロンプトの表示が停止します。予想外の場合、これは少し当惑させられます。 echo on
と入力すると、通常の動作に戻ります。
(わかりやすくするために前のセクションを編集し、実際に何が起こっているのかを文書化するためにこのセクションを追加しました。)
.BATおよび.CMDスクリプトを解釈し、最新のWindowsで対話型コマンドPromptを提供するCMD.EXE
プログラムは、驚くほど十分に文書化されていますが、事実上文書化されていません。アットマークがこの効果を持ち、正確にどこで使用できるかを説明する公式文書を検索する私の試みは、ほとんど失敗しました。
アットマークがコマンドの最初の非空白文字として表示される場合、アットマークが解析および解釈されることは実験から明らかです。上記の「声明の冒頭」という言葉を使ってそれを表現しようとしました。
私の知る限り、CMDの言語用に公開された正式な文法はありません。ただし、CDM自体のドキュメント(プロンプトにcmd /?
を入力)、およびif /?
と、他の「興味深い」組み込みコマンドの組み込みヘルプテキストから、 CMDがソーステキストを解析するときに続きます。
コマンドの開始は、行の先頭、またはif
の条件の後、else
の後、または開き括弧(
の後のように見えます。アットマークが認識されると、そのコマンドの残りの(ほとんど)に適用されます。
次のバッチファイルを自分で試して、アットマークを動かしてみてください。ルールを正確に記述するのが難しいという感覚がすぐにわかります。
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
Win 7 Proで実行すると、次のように表示されます。
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...>
BATファイルの細部のほとんどと同様に、スクラッチした表面の下には謎があります。
括弧を設定します(docu ...を参照):
IF DEFINED TEAMCITY_PROJECT_NAME (@ECHO ON) ELSE @ECHO OFF
ECHO
はデフォルトでオンになっているようです。そのため、条件付きでテストすると、IF
ステートメントが出力されます。あなたはから始めるべきです
@ECHO OFF
そして、評価する別のステートメントとして条件を追加します
@ECHO OFF && IF DEFINED TEAMCITY_PROJECT_NAME @ECHO ON
以前の応答で述べたように、ECHOはデフォルトでオンになっています。同じ動作を実現する別の方法は次のとおりです。
@if "%TEAMCITY_PROJECT_NAME%" == "" @echo off