バッチファイル
拡張子 | .bat, .cmd (Windows NT) |
---|---|
MIMEタイプ | application/x-bat |
種別 | スクリプト言語 |
バッチファイル(英: batch file)とは、MS-DOS、OS/2、Windowsでのコマンドプロンプト(シェル)に実行させたい命令列をテキストファイルに記述したもの。バッチファイルを実行すると、シェルプログラム(一般にCOMMAND.COM
やcmd.exe
)がそのファイルを読み、その中のコマンドを(通常)一行ずつ実行する[1]。バッチファイルはUNIX系オペレーティングシステムのシェルスクリプトに相当する。
DOSのバッチファイルの拡張子は.BAT
である。他の環境のバッチファイルの拡張子は様々である。例えば、Windows NTやOS/2では.CMD
が使われており[2]、4DOS(英語版) というフリーウェアでは .BTM
が使われている[3]。
AUTOEXEC.BAT
はブート処理の中で実行される特別なバッチファイル(自動実行バッチファイル)である。
歴史
マイクロソフトのDOSとWindowsのバッチプログラミングはこれらのオペレーティングシステム (OS) 製品のリリースとともに発展してきた。これらOSに付属するコマンドインタプリタは2つの動作モードを持つ。一つは対話モード(コマンドプロンプトに従ってユーザーがコマンドを入力すると即座に実行される)とバッチモード(予め設定されたコマンド列を実行する)である。どちらのモードもUNIXのシェルや1980年代初期のCP/Mなどのコマンドインターフェイスがその考え方のベースとなっている。
MS-DOSオペレーティングシステムのバッチプログラム用インタプリタはCOMMAND.COM
である。MS-DOS用バッチプログラムのうち比較的単純なコマンドはCOMMAND.COM
自身が処理し(内部コマンド)、複雑なものは別の実行ファイルを呼び出して処理する(外部コマンド)。この系統のバッチプログラミングはMS-DOSからWindows 95、Windows 98、Windows Me(Windows 9x系)まで発展していった。
Windows 2000およびWindows XP以降はMS-DOSではなくWindows NTに基づいている。この系統(Windows NT系)ではcmd.exe
というコマンド行インタプリタが使われ、COMMAND.COM
とはある程度の互換性がある。MS-DOSのいくつかの機能が削除されているが、MS-DOSやMS-DOSベースのWindowsにはない新たな機能も多く追加されている。互換性維持のためCOMMAND.COM
も未だに搭載されている。
2006年には.NET Frameworkを基盤に動作する、モダンなオブジェクト指向のシェル環境としてWindows PowerShellがリリースされた。Windows PowerShellではdir
などの従来のWindowsコマンドに対するエイリアスが用意されており、完全ではないがある程度の互換性がある。PowerShellはWindows以外の環境にも.NET Coreベースで移植されている。
代表的なコマンド
echo
echo
コマンドは標準出力にメッセージを表示する。メッセージ文字列をダブルクォーテーションやシングルクォーテーションなどで囲む必要はない。
また、echo on
およびecho off
でコマンドエコーのON/OFFを切り替えることができる。コマンドエコーは既定でONになっており、各コマンド行を実行する前に標準出力にその内容を表示する[4]。この動作は通常必要とされないので、echo off
コマンドをバッチファイルの最初に記述してそれを防ぐ。しかし、そのままでは echo off
コマンド自体は表示されてしまう。単価記号 @
をコマンド行の先頭に置くと、その行は表示されないようになっているので、多くのバッチファイルには @echo off
という行が先頭にある。
rem
コメント行はrem
で始める。rem
もコマンドの一種である[5]。
cls
テキスト画面を削除する。
call
別のバッチファイルやラベルで指定したプログラムに処理を移す。バッチファイルにはローカル変数とグローバル変数の概念があり、サブルーチンの中でメインルーチンにある変数と同じ名前の変数を使っても区別される。
for[6]
他の多くのプログラミング言語と同じように指定した回数ループすることができるコマンドであるが、それのみならずフォルダ内のすべてのファイルを確認しそれらのファイルに対して処理を行うなどと行ったこともできる。基本的には、
for (オプション) %%変数名 in (ループの対象) do(コマンド)
という書式になる。オプションとして何も指定しない場合はinで指定したディレクトリの中のファイル名1つを%%のあとに指定したアルファベット一文字の変数に代入してからdoの中の処理を行う。ファイルが無くなったら中断する。つまりファイルがなくならないようなプログラムを作ってしまうと無限ループになる。/rをオプションに指定すると、サブディレクトリまでも対象にする。
オプションとして/dを指定すると、inで指定したディレクトリの中のディレクトリ名が1つ変数に代入されてから、doの中の処理を行う。
/lは一般的なプログラミング言語における指定した回数のループを行う。その場合の書式は次のようになる。
for /l %%変数 in (開始値、増分、終了値) do コマンド
まず開始値で指定した数値が変数に代入され、doの中の処理が行われる。doの中の処理が終わると、変数の値が増分値で指定した分だけ増加し、またdo内の処理が行われる。変数の値が終了値に達すると処理が終了する。
cd
指定したディレクトリに移動することができる。cdで移動したディレクトリより階層が深いところにあるファイル、フォルダは、相対パスで参照可能になる。
dir
指定したディレクトリの中のファイルのリストを表示する。これを使ってテキストファイル形式のファイルリストを作ることができる。オプションを設定することで特定のファイルのみ表示することもできる。
shift[7]
これを実行すると呼び出し時に渡された引数を一つずらすことができる。オプションはない。
使用例:バッチファイルの引数は、仕様によって10個未満(9個以下)までしか引数を指定できない。なので、10つ以上指定する場合は、shiftコマンドを利用する。
起動引数:
test.bat ar1 ar2 ar3 ar4 ar5 ar6 ar7 ar8 ar9 ar10
コード:
@echo off shift echo 第9引数は%9です。
出力:
第9引数はar10です。
特殊な変数[8]
バッチファイル(コマンドプロンプト)には、コマンドの後の返り値、呼び出し時の引数、システムの設定などで値が変わる特殊な変数がある。
%1,%2,%3...%9
これは変数というより引数に近く、バッチファイルが呼び出された時に指定された引数を前から順番に1,2,3,4...の順で参照できる。注意点として、引数は10個までしか指定できないということ。10個以上指定する場合は、shiftコマンドを利用する。
%CD%
cdコマンドなどで指定したディレクトリのパス。この値はcdコマンドなどで変えられる。
%DATE%
現在の日付。これはシステムに依存する。システムの設定や、dateコマンドで変更できる。
%TIME%
現在の時刻。これもシステムに依存する。形式はhh:mm:ss.msである。
%RANDOM%
0から32767までのランダムな整数。for文の中で複数回呼び出しても値は変わらないが、for文の外ならば呼び出されるごとに値が変わる。ちなみに、32767は符号なし15bit整数の最大値である。
%ERRORLEVEL%
直前のコマンドが正常終了したか、または異常終了したかを数値で表したもの。一般的に、0が正常終了で、-1が異常終了である。これはif文と組み合わせて使う。
%CMDEXTVERSION%
現在の拡張機能のバージョン番号。cmdコマンドで拡張機能を指定してコマンドプロンプトを起動できる。
%HIGHESTNUMANODENUMBER%
コンピューター上の最大NUMAノード番号。使うことは滅多にない。
変数の読み込みタイミング[9]
set num=1 if %num% == 1 ( set /a num+=1 echo %num% ) pause
このプログラムは、変数numを表示するように書いているので、変数numに加算されて「2」と表示されるはずが、このコードでは「2」ではなく「1」と表示される。この原因は、if文に入った時点で変数numが固定(厳密には展開)されるので、変数に加算はされるが表示するものは「1」で固定されているので、「1」と表示される。
これを回避するには、2つの方法がある。
「!」で囲って参照する方法
この変数が展開されるのを防ぐには、「!」で囲うという方法がある。
「!」で参照すると、その変数を読み込むタイミングが、『行に入った瞬間』から『その変数を使うコマンドにたどり着いた瞬間』になる。
そのため、上記のコードを「!」で囲うと、通常通り加算されて「2」と表示される。
setlocalコマンドを使う方法
もう一つの方法は、setlocal enabledelayedexpansion
を先頭に記述する方法だ。
これを使うことにより、「!」で囲った時と同じ効果が得られる。
ちなみに、setlocal enabledelayedexpansion
を解除する方法は、解除したい行でendlocal
を入力するだけだ。
例
- 単純なバッチファイルの例:
@echo off cls echo. echo Hello World, press any key to start AProgram.exe! pause > nul AProgram.exe echo. echo AProgram has finished whatever it was doing. Have fun today!
画面出力:
Hello World, press any key to start AProgram.exe! AProgram has finished whatever it was doing. Have fun today!
@echo off echo Hello world!! pause > nul
画面出力:
Hello world!!
- 3の倍数ならFizz、5の倍数ならBuzz、15の倍数ならFizz Buzzと表示し、FizzBuzz.txt に結果を出力
@echo off setlocal enabledelayedexpansion cd /d %~dp0 if exist %cd%\FizzBuzz.txt del %cd%\FizzBuzz.txt for /l %%i in (1,1,100) do ( set echo= set /a f=%%i%%3,b=%%i%%5 if !f!==0 set echo=!echo!Fizz if !b!==0 set echo=!echo!Buzz if "!echo!"=="" set echo=%%i echo !echo!>>%cd%\FizzBuzz.txt )
画面出力:なし
- FFmpegでエンコード バッチファイルの置かれたディレクトリを終了するまで10秒おきに監視して、tsファイルを発見次第バッチファイルと同じフォルダに置かれたffmpeg.exeでmp4にエンコードしたあと、元のファイルを削除する。 エンコードされたファイルが既に存在する場合は上書きする。まず、forループでファイルが有るかどうかチェックする。見つかったファイルは:encodeというサブルーチンに渡される。これはエンコード後のファイル名をつける際の%~n1で元のファイルのファイル名だけを抽出する必要があるからだ。 encodeの中でファイルをffmpegに渡してエンコードし、その後delコマンドでファイルを削除したら、サブルーチンが終了し、メインルーチンに戻る。tsファイルがまだ残っていれば再びエンコードする。なければforループから抜け出し、10秒間待機する。再びtsファイルを発見すると順次エンコードする。
echo off cd %~dp :loop for %%i in (*.ts) do ( call :encode %%i% ) timeout 10 goto :loop :encode ffmpeg.exe -i "%1" -vf bwdif=1 -c:v libx264 -c:a copy -bsf:a aac_adtstoasc ^ -preset fast -aspect 16:9 -b:v 5500k -y "%~n1.mp4" del %1 exit /b
互換コマンドインタプリタ
マイクロソフト以外が提供するコマンドインタプリタにも様々なコマンドインタプリタがあり、強化された機能を提供している。4DOS(英語版) はその一例である。
バッチプログラムを実行ファイルに変換するコンパイラもマイクロソフト以外からいくつか登場しているが、その品質は様々である。
IBMのOS/2オペレーティングシステムもマイクロソフトのOSと似たようなテキストベースのコマンド機能を持っている。
脚注
- ^ waitforコマンドを使えば同期処理ができる。
- ^ “.cmdファイルとは - IT用語辞典”. IT用語辞典 e-Words. 2022年8月11日閲覧。
- ^ “IT用語辞典【 バッチファイル の意味と同義語 】”. www.pastem.jp. 2022年8月11日閲覧。
- ^ echo | Microsoft Docs
- ^ rem | Microsoft Docs
- ^ “.bat(バッチファイル)のforコマンド解説。”. Qiita. 2021年3月6日閲覧。
- ^ “shift(引数をずらして格納しなおす)”. 知識ゼロからのwindowsバッチファイル超入門. 2022年8月10日閲覧。
- ^ Src="https://Secure.gravatar.com/Avatar/?s=34, <img Alt=. “バッチファイルで変数を使う”. 知識ゼロからのwindowsバッチファイル超入門. 2022年8月8日閲覧。
- ^ “バッチファイル界の魔境『遅延環境変数』に挑む(おまけもあるよ)”. Qiita. 2022年8月9日閲覧。
関連項目
- シェルスクリプト
- バッチ処理
- フィルター - フィルタ (ソフトウェア)
- パイプ
- ジョブ
- ジョブ管理システム
- Windows Script Host
- Windows PowerShell
外部リンク
- Windows Commands | Microsoft Docs