バッチファイルは、 DOS、OS/2、およびMicrosoft Windowsにおけるスクリプトファイルです。コマンドラインインタープリタによって実行される一連のコマンドが、プレーンテキストファイルに格納されています。バッチファイルには、インタープリタが対話的に受け入れるあらゆるコマンドを含めることができ、条件分岐やループを可能にする構造(`< input type= " bind" > `、IFFORGOTO
ジョブ制御言語(JCL)、DCL、およびメインフレームやミニコンピュータシステムの他のシステムと同様に、バッチファイルは、ユーザーがスクリプトを設定して自動化できるようにすることで、特定の定型タスクに必要な作業を容易にするために追加されました。バッチファイルを実行すると、シェルプログラム (通常はCOMMAND.COMまたはcmd.exe ) がファイルを読み込み、通常は行ごとにコマンドを実行します。[ 1 ] LinuxなどのUnix ライクなオペレーティングシステムには、シェルスクリプトと呼ばれる、これと似ているが、より柔軟なタイプのファイルがあります。[ 2 ]
ファイル名拡張子「.bat」は、DOSとWindowsで使用されます。Windows NTとOS/2では「.cmd」も追加されました。その他の環境向けのバッチファイルには、異なる拡張子が使用される場合があります。例えば、4DOS、4OS2、4NT関連のシェルでは「.btm」が使用されます。
バッチファイルの詳細な処理方法は、バージョン間で大きく変更されています。この記事で説明する内容の一部はすべてのバッチファイルに当てはまりますが、その他の内容は特定のバージョンにのみ適用されます。
MS-DOSでは、バッチファイルの名前を入力し、必要なパラメータを続けてキーを押すことで、コマンドラインインターフェースからバッチファイルを起動できます。DOSが起動すると、 AUTOEXEC.BAT↵ Enterファイルが存在する場合は自動的に実行されるため、DOS環境をセットアップするために実行する必要のあるコマンドはこのファイルに記述できます。コンピュータユーザーは、AUTOEXEC.BATファイルを使用して、システムの日付と時刻を設定したり、DOS環境を初期化したり、常駐プログラムやデバイスドライバをロードしたり、ネットワーク接続や割り当てを初期化したりすることができます。
.bat というファイル名拡張子は、コマンドインタープリタCOMMAND.COMによって一行ずつ実行されるコマンドを含むファイルを識別します。これは、手動で入力されたコマンドのリストであるかのように扱われ、基本的なプログラミング機能のためのバッチファイル固有の追加コマンド(GOTO行の実行フローを変更するコマンドなど)も含まれています。
Microsoft Windowsは、テキストベースのオペレーティングシステムにグラフィカルユーザーインターフェース(GUI)を重ねたものとして1985年に導入され、DOS上で動作するように設計されました。起動するには、AUTOEXEC.BATファイルの末尾にコマンドを追加することで、Windowsの自動起動を可能にするコマンドが使用されました。初期のバージョンでは、MS-DOSプロンプトからWindows上で.batタイプのファイルを実行することができました。Windows 3.1x以前およびWindows 9xでは、バッチファイルを実行するためにCOMMAND.COMが呼び出されました。WIN
IBM OS/2オペレーティングシステムは、 DOSスタイルのバッチファイルをサポートしていました。また、より高度なバッチファイルスクリプト言語であるREXXのバージョンも含まれていました。IBMとMicrosoftはこのシステムの開発を開始しましたが、開発中に意見の相違から提携を解消しました。そのため、IBMはMicrosoftに言及することなく、DOSライクなコンソールシェルを単にDOSと呼ぶようになりました。ただし、これはCOMMAND.COMからのバッチファイルの動作方法には影響を与えなかったようです。
OS/2のバッチファイルインタープリタは、EXTPROCコマンドもサポートしています。このコマンドは、バッチファイルをEXTPROCファイルで指定されたプログラムにデータファイルとして渡します。指定されたプログラムはスクリプトファイルでも構いません。これは、Unix系オペレーティングシステムで使用される#!メカニズムに似ています。
Windows 98以前のOSとは異なり、 Windows NTファミリーのオペレーティングシステムはMS-DOSに依存していません。Windows NTでは、拡張子が.CMDまたは.BATのスクリプトを実行できる、拡張された32ビットコマンドインタープリタ(cmd.exe)が導入されました。cmd.exeはコマンドを追加し、既存のコマンドも若干異なる方法で実装したため、同じバッチファイル(拡張子が異なる場合)でもcmd.exeとCOMMAND.COMでは動作が異なる場合があります。サポートされていない少数のコマンドを使用しない限り、ほとんどの場合、動作は同じです。互換性のために、cmd.exeのCOMMAND.COMへの拡張機能を無効にすることができます。
マイクロソフトは、Windows 9xおよびME向けにWIN95CMDと呼ばれるcmd.exeのバージョンをリリースし、古いバージョンのWindowsのユーザーが特定のcmd.exe形式のバッチファイルを使用できるようにした。
Windows 8以降cmd.exe はバッチファイルの通常のコマンドインタープリタです。古い COMMAND.COM も、16 ビット プログラムを実行できる 32 ビット版 Windows で実行できます。[ nb 1 ]
appendコマンドdpathはftype、set.batファイルから実行されると、エラーが発生した場合にのみ変数の値を変更しますが、.cmd ファイル内から実行されると、エラーが発生しなくても戻り値に影響します。[ 3 ] IBM の OS/2 でもバッチ ファイルで使用されています。pathassocprompterrorlevelCOMMAND.COMとcmd.exe は、ファイル名に拡張子が付いていなくてもバッチファイルを実行できます。たとえば、 とDoThis入力すると、インタープリタはCOM、 、.EXE、.BAT、.CMD、 およびこのトピックとは関係のない他の 7 つの拡張子を、指定された順序で試します。PATHEXT環境変数を使用すると、上記 のデフォルト設定を変更できます。
COMMAND.COM および cmd.exe は、バッチ ジョブのパスと名前、およびバッチ ジョブ内からの最初の 9 つの呼び出しパラメーターを参照するために、特殊変数 ( %0、%1から) をサポートしています。 も参照してください。存在しないパラメーターは、長さゼロの文字列に置き換えられます。これらは環境変数と同様に使用できますが、環境には保存されません。Microsoft および IBM はこれらの変数を置換パラメーターまたは置換可能パラメーターと呼んでいますが、Digital Research、Novell、および Caldera は置換変数[ 5 ]という用語を確立しました。JP Software はこれらをバッチ ファイル パラメーターと呼んでいます。[ 6 ]%9SHIFT
このサンプルバッチファイルはHello World!、画面を表示し、ユーザーにキーを押すよう促して待機した後、終了します。(コマンドは小文字でも大文字でも構いませんが、変数名は大文字と小文字を区別します。)
@ ECHO OFF ECHO Hello World! PAUSEファイルを実行するには、ファイル名の拡張子を .bat (Windows NT 系オペレーティングシステムの場合は .cmd) にして、プレーンテキスト形式で保存する必要があります。通常、Microsoft メモ帳などのテキストエディタ、またはプレーンテキストモードで動作するワープロソフトを使用して作成します。
実行すると、以下が表示されます。
「こんにちは世界」 続行するには任意のキーを押してください...
インタープリタは、最初の行から順に各行を実行します。@行の先頭にある記号は、そのコマンドが実行されるときにプロンプトにそのコマンドが表示されないようにします。このコマンドは、ECHO OFFプロンプトを永久にオフにするか、再びオンになるまでオフにします。この組み合わせは、@ECHO OFF多くの場合、ここに示されているようにバッチ ファイルの最初の行であり、自身を含め、どのコマンドも表示されないようにします。次に、次の行が実行され、ECHO Hello World!コマンドは を出力しますHello World!。次の行が実行され、PAUSEコマンドが表示されPress any key to continue . . .、スクリプトの実行が一時停止します。キーが押されると、コマンドがなくなるため、スクリプトは終了します。Windows では、スクリプトが既に実行中のコマンド プロンプトウィンドウから実行されると、MS-DOS と同様にプロンプトでウィンドウが開いたままになります。そうでない場合は、終了時にウィンドウが閉じます。
変数展開はコマンドにテキストとして代入されるため、何も含まれていない変数は構文から消え、スペースを含む変数は複数のトークンに変換されます。これは構文エラーやバグの原因となる可能性があります。
例えば、%foo% が空の場合、このステートメントは次のようになります。
IF %foo% == bar ECHO等しい 誤った構造として解析されます。
IF ==bar ECHO 等しい同様に、%foo%が含まれている場合abc def、別の構文エラーが発生します。
IF abc def == bar ECHO等しい この問題を回避する一般的な方法は、変数展開を引用符で囲むことです。そうすることで、空の変数がIF ""=="bar"無効な式ではなく、有効な式に展開されますIF ==bar。変数と比較されるテキストも引用符で囲む必要があります。なぜなら、引用符は特別な区切り記号ではなく、それ自体を表す文字だからです。
IF " %foo% " == "bar" ECHO等しい Windows 2000以降で利用可能な遅延!VARIABLE!展開を使用すると、これらの構文エラーを回避できます。この場合、値がIFコマンドの解析後に展開されるため、null変数や複数単語の変数でも構文エラーにはなりません。
IF !foo! == bar ECHO等しい Windows 2000以降では、空の変数(未定義)が置換されないという違いがあります。前の例で説明したように、以前のバッチインタープリタの動作では空の文字列が生成されていました。例:
C:\> set MyVar = C:\> echo %MyVar% %MyVar%C:\> if " %MyVar% " == "" ( echo MyVar は定義されていません) else ( echo MyVar は%MyVar%です) MyVar は %MyVar% ですWindows 2000 より前のバッチ インタープリタでは、結果が表示されていましたMyVar is not defined。
Unix/POSIXプロセスは、シェルによって既に文字列の配列に分割されたコマンドライン引数を受け取りますが、WindowsプロセスはGetCommandLine API関数を介して、コマンドライン全体を単一の文字列として受け取ります。そのため、各Windowsアプリケーションは、コマンドライン全体を引数に分割するための独自のパーサーを実装できます。多くのアプリケーションやコマンドラインツールは、このための独自の構文を発展させてきたため、 Windowsコマンドラインにおけるメタ文字の引用符付けやエスケープに関する統一された規則は存在しません。
cmd.exeやなどwscript.exe独自のルールを使用するものがあります。[ 8 ]文字列に引用符が含まれており、その文字列を引用符で囲む必要のある別の行のテキストに挿入する場合、引用符の仕組みに特に注意を払う必要があります。
C:\> set foo = "この文字列は引用符で囲まれています"C:\> echo "test 1 %foo% " "test 1 "この文字列は引用符で囲まれています"C:\> eventcreate /T Warning /ID 1 /L System /SO "Source" /D "Example: %foo% "エラー: 無効な引数/オプション - 'string'。使用方法については「EVENTCREATE /?」と入力してください。Windows 2000以降では、値の中にある引用符文字を、3つの引用符文字の連続に置き換えることで解決できます。
C:\> set foo = "この文字列は引用符で囲まれています"C:\> set foo = %foo:"="""%C:\> echo "test 1 %foo% " "test 1 """この文字列は引用符で囲まれています""""C:\> eventcreate /T Warning /ID 1 /L System /SO "Source" /D "Example: %foo% "成功: 'Source' ログ/ソースに 'Warning' タイプのイベントが作成されました。パイプ記号()などの一部の文字は|、コマンドラインにおいて特別な意味を持ちます。これらの文字は、キャレット記号(^)でエスケープしない限り、ECHOコマンドでテキストとして出力することはできません。
C:\> echo foo | bar 'bar' は、内部コマンドまたは外部コマンド、操作可能なプログラムまたはバッチ ファイルとして認識されません。C:\> echo foo ^| bar foo | barしかし、エスケープ文字を環境変数に挿入する場合、エスケープ処理は期待どおりに機能しません。単にエコーするだけで、変数には有効なパイプコマンドが含まれてしまいます。変数内の文字をテキストとして表示するには、キャレット自体とエスケープ文字の両方をエスケープする必要があります。
C:\> set foo = bar | baz 'baz' は、内部コマンドまたは外部コマンド、操作可能なプログラムまたはバッチ ファイルとして認識されません。C:\> set foo = bar ^| baz C:\> echo %foo% 'baz' は、内部コマンドまたは外部コマンド、操作可能なプログラムまたはバッチ ファイルとして認識されません。C:\> set foo = bar ^^^| baz C:\> echo %foo% bar |バズWindows 2000以降で利用可能な遅延展開は、環境変数に格納されている特殊文字を表示するために使用できます。これは、コマンドが解析された後に変数の値が展開されるためです。
C:\> cmd /V:ON Microsoft Windows [バージョン 6.1.7601] Copyright (c) 2009 Microsoft Corporation. All rights reserved.C:\> set foo = bar ^| baz C:\>エコー!foo!バー |バズWindows VistaでTIMEOUTコマンドが導入されるまでは、PAUSEコマンドはキーが押されるまでスクリプトの動作を無期限に停止してしまうため、時間指定の一時停止を簡単に実装する方法はありませんでした。
多くの回避策は可能でしたが、[ 10 ]一般的には一部の環境でしか機能しませんでした。CHOICE古い DOS バージョンではコマンドが利用できず、PINGTCP/IP がインストールされている場合にのみ利用可能でした。Microsoft からは解決策は提供されていませんでしたが、他のソースからいくつかの小さなユーティリティ プログラムをインストールできました。商用の例としては、1 秒間待機する 1988 の Norton Utilities Batch Enhancer (BE) コマンドや、5 秒間待機してからスクリプトに制御を戻すBE DELAY 1894 バイトの無料 WAIT.COM [ 11 ]WAIT 5があります。このようなプログラムのほとんどは 16 ビットの .COM ファイルであるため、64 ビット Windows と互換性がありません。
通常、印刷されたテキストには、各行の末尾に自動的にキャリッジリターン(CR)とラインフィード(LF)の制御文字が付加されます。
@ echo foo @ echo bar C:\> batchtest.bat foo bar2つのechoコマンドが同じコマンド行を共有していても問題ありません。CR/LFコードは、出力を別々の行に分割するために挿入されます。
C:\> @ echoメッセージ 1 &@ echoメッセージ 2 メッセージ 1メッセージ 2Windows 2000以降で発見されたテクニックとして、入力用の特殊なプロンプトを使用して、テキストの末尾にCR/LFを付けずにテキストを出力する方法があります。この例では、CR/LFはメッセージ1の後には付きませんが、行2と行3の後には付きます。
@ echo off set /p = "メッセージ 1" < nul echoメッセージ 2 echoメッセージ 3 C:\> batchtest2.bat メッセージ1 メッセージ2メッセージ3これは、末尾にCR/LFを追加せずにテキストファイルにデータを出力する場合に使用できます。
C:\> set /p = "メッセージ 1" < nul > data.txt C:\> set /p = "メッセージ 2" < nul >> data.txt C:\> set /p = "メッセージ 3" < nul >> data.txt C:\> type data.txt メッセージ 1 メッセージ 2 メッセージ 3しかし、CR/LFが削除されたこのプロンプト出力を環境変数に直接挿入する方法はありません。
UNC パスを現在の作業ディレクトリとして使用するコマンド プロンプトは存在しません。例:\\server\share\directory\
コマンドプロンプトでは、作業ディレクトリを割り当てるためにドライブ文字を使用する必要があるため、サーバーの UNC 共有に保存されている複雑なバッチ ファイルを実行するのが難しくなります。バッチ ファイルは UNC ファイル パスから実行できますが、作業ディレクトリのデフォルトは ですC:\Windows\System32\。
Windows 2000 以降では、回避策として、コマンド拡張機能付きのコマンドPUSHDとPOPDコマンドを使用します。[ nb 2 ]
デフォルトで有効になっていない場合、コマンド拡張機能は/E:ONコマンドインタープリタのスイッチを使用して一時的に有効にすることができます。
UNC共有上でバッチファイルを実行するには、UNC共有に一時的なドライブ文字を割り当て、UNC共有をバッチファイルの作業ディレクトリとして使用するように、次のようなWindowsショートカットを作成できます。
このショートカットの作業ディレクトリ属性は無視されます。
これは、Windows Vista 以降のユーザー アカウント制御(UAC)に関連する問題も解決します。管理者がログオンしていて UAC が有効になっている場合、右クリックのファイルコンテキスト メニューを使用してネットワーク ドライブ レターからバッチ ファイルを管理者として実行しようとすると、操作が予期せず失敗します。これは、昇格された UAC 特権アカウント コンテキストにはネットワーク ドライブ レターが割り当てられておらず、エクスプローラ シェルやログオン スクリプトを使用して昇格されたコンテキストにドライブ レターを割り当てることができないためです。しかし、上記のPUSHD/POPD構文を使用してバッチ ファイルへのショートカットを作成し、そのショートカットを使用してバッチ ファイルを管理者として実行すると、昇格されたアカウント コンテキストで一時的なドライブ レターが作成されて削除され、バッチ ファイルが正しく機能します。
以下の構文は、現在のバッチスクリプトのパスに正しく展開されます。
%~dp0
UNC のデフォルト パスは、古いプログラムがクラッシュする原因となっていたため、デフォルトでは無効になっています。[ 12 ]
[ 12 ]DisableUNCCheckのDword レジストリ値により、デフォルト ディレクトリを UNC にすることができます。コマンドは変更を拒否しますが、Cmd へのショートカットのデフォルト ディレクトリに UNC パスを配置するか、スタート コマンドを使用します。(共有は管理者向けです)。HKEY_CURRENT_USER\Software\Microsoft\Command ProcessorCDC$
バッチ ファイルは、コンピュータによって定義された OEM 文字セット (例:コード ページ 437)を使用します。これらの文字セットの非 ASCII 部分は、 Windows で使用されているUnicodeまたはWindows 文字セットと互換性がないため、注意が必要です。[ 13 ]英語以外のファイル名は、DOS 文字セット互換のエディタで入力した場合にのみ機能します。このセット外の文字を含むファイル名は、バッチ ファイルでは機能しません。
コードページ437などではなくUnicodeを使用したコマンドプロンプトを取得するには、cmd /Uコマンドを使用できます。このようなコマンドプロンプトでは、Unicodeファイル名を含むバッチファイルが動作します。また、Unicodeを文字セットとしてコマンドを直接実行することもできますcmd /U。たとえば、UTF-16 LEエンコーディングで正しいWindows文字を含むディレクトリ一覧を記述したファイルを作成します。cmd /U /C dir > files.txt
他のプログラミング言語と同様に、バッチファイルも悪用される可能性があります。単純なトロイの木馬やフォーク爆弾は簡単に作成でき、バッチファイルはホストファイルを変更することでDNSポイズニングの一種を実行できます。バッチウイルスも存在し、Windowsの自動実行機能を利用してUSBフラッシュドライブを介して拡散することもできます。[ 14 ]
バッチファイル内の以下のコマンドは、確認を求めることなく、現在のディレクトリ(フォルダ)内のすべてのデータを削除します。
del /Q *.* これら3つのコマンドは、利用可能なシステムリソースを枯渇させ、システムを遅くしたりクラッシュさせたりするために、自己複製を繰り返す単純なフォーク爆弾です。
: TOP開始"" %0 TOPへ移動とファイルの両方を解釈するcmd.exeコマンドプロセッサは、 Windows NTファミリー、Windows CE、およびReactOSのすべてのバージョンでサポートされています。ファイルのみを解釈する旧バージョンのCOMMAND.COMは、Windows 9xおよびWindows NTの32ビット版で利用可能ですが、厳密に64ビット版であるWindows 11では利用できません。.bat.cmd.bat
しかし、Microsoft Windowsには、より高度なスクリプト環境が付属している。
cscript.exewscript.exewscript.execscript.exemshta.exeで構成されるグラフィカルにリッチなスクリプトを作成する手段です。Windowsには他にもスクリプト言語が用意されています。ただし、これらを使用するには、事前にスクリプト言語インタープリタをインストールする必要があります。
COMMAND.COM32 ビット版 Windows 7 のコマンド プロンプトで次のように入力します。inQuotes 領域内の 2 つの連続する二重引用符は、リテラルの二重引用符になります (パーサーは inQuotes 領域内に残ります)。この動作は code:ParseArgumentsIntoList の仕様の一部ではありませんが、CRT および .NET Framework と互換性があります。