技術とか戦略とか

SIerで証券レガシーシステムを8年いじってからSESに転職した普通の文系SEによる技術ブログ。

初めてのWindowsバッチ

Windowsバッチを作ったことが無い方向けに、Windowsバッチの用途や使い方を書いた入門的な記事です。
詳しいコマンドの使い方は記載しませんので、必要に応じて調べてみて下さい。
 
Windowsバッチとは】
WindowsOSに標準で用意されている実行ファイル形式であり、拡張子は.batである。
エクスプローラ上でダブルクリックすることで、記述されたDOSコマンド(スクリプト)を自動実行することができる。
簡単な制御や実行ファイル呼び出しを記述可能で、要件に合わせて一連の処理を取りまとめたい時に使用される。
 
WindowsバッチでHello WorldWindowsバッチの導入)】
WindowsOSであることが前提です。
 
1.エクスプローラを開き、表示 > ファイル名拡張子 のチェックを入れる。
f:id:akira2kun:20200614200559j:plain

2.任意の名前でテキストドキュメントを新規作成した後、ファイルの名前を変更する。拡張子を「.txt」から「.bat」に変更する。
3.2で作成したファイルを 右クリック > 編集 で選択し、下記のように入力して保存する。
@echo off
echo Hello World!
pause
4.3で編集したファイルをダブルクリックする。コンソールが表示され、下記のように表示されればOK。
Hello World!
続行するには何かキーを押してください . . .
 
Windowsバッチでできること】
Windowsバッチは複雑な処理を記述するには不向きですが、下記で挙げるような処理であれば記述可能です。
実行ファイルを部品として組み合わせる分には困ることは少なく、「WindowsOSであれば初期設定無しで動く」「習得が容易で、エンジニアであればメンテナンスできる人も多い」といった特徴から、気軽に導入することができます。
 
1.コンソールへの文字列表示(標準出力)
Hello Worldの例の通り、コンソールへの文字列表示が可能です。
"echo "の後に表示させたい文字列を記述することで、その文字列を表示することができます。
なお、Windowsバッチでは実行されるコマンドもコンソールに表示されるのですが、"@echo off"と記述すれば以降はコマンドのコンソール表示を抑止することができます。
また、Windowsバッチは全てのコマンドの実行が完了したら自動的にウインドウを閉じてしまうので、表示内容を確認したい場合は"pause"と記述して一時的に処理を中断(任意のキー押下で再開)する必要があります。
 
2.外部の実行ファイルの実行
実行ファイルのパスを記述することで、Windowsバッチから外部の実行ファイルを実行することができます。
実行ファイルのパスの後にスペース区切りで文字列を入力すれば、その文字列を引数として与えることもできます。
 
例えば、下記のように記述すれば、WindowsOS標準のプログラム言語「C#」のコンパイラを起動することができます。
C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe コンパイルしたいC#ソースファイルのパス
 
C#コンパイル済み実行ファイル(.exe)やjavaコンパイル済み実行ファイル(.jar)があるなら、そのファイルのパスを記述することでその実行ファイルを実行することができます。
下記は、C#の実行ファイル C:\tmp\Program.exe を実行する例です。
C:\tmp\Program.exe
 
また、Windowsバッチよりも強力な機能を持ったWindowsOS標準のスクリプト言語Windows Power Shell」は、OSの設定によってはダブルクリックで実行できないという難点があるのですが、下記のように記述することで設定問わずダブルクリックで実行できるようになります。
Windows Power Shell は環境変数でパスが通っているので、実行ファイルのパスの指定は不要です)
powershell -ExecutionPolicy RemoteSigned -File 実行したいWindows Power Shellファイルのパス
 
ダブルクリックするだけで引数付きで実行ファイルを実行したり、複数の実行ファイルを実行したり、Windows Power Shell のスクリプトを実行したりできるので、単純に外部の実行ファイルの実行したい時にもWindowsバッチのファイルを作る価値があります。
難しい処理はC#Windows Power Shell等で記述し、実行はバッチファイルから行う、というスタイルがWindowsOSの場合は馴染みやすいと思います。
 
3.現在のパス(カレントディレクトリ)の変更
Windowsバッチでは、実行直後はWindowsバッチのファイルが存在するパスを指しています。
例えば、C:\tmp\hoge.bat を実行した場合、実行直後のパスは C:\tmp\ となります。
ファイルのパス指定は現在のパスを起点に相対パスで指定することができ、例えば C:\tmp\ にいる場合は、C:\tmp\Program.exe を
.\Program.exe
と指定して実行することが可能です。
(.\は省略することも可能です)
 
現在のパス(カレントディレクトリ)を変更したい場合は、cdコマンドで変更することができます。
cdコマンドのパス指定は絶対パスでも相対パスでも可能で、例えば C:\tmp\ から C:\hoge\ に移動したい場合は、
cd ..\hoge\
で移動できます。
 
他の環境でもWindowsバッチを動かしたい場合は、相対パスが便利です。
 
4.フォルダの作成
Windowsバッチでは、mkdirコマンドでフォルダを作成することができます。フォルダ名には絶対パス・フルパス両方指定可能です。
mkdir フォルダ名
 
なお、フォルダを削除することもでき、コマンドはrmdirコマンドです。
 
5.ファイルの作成
Windowsバッチでは標準出力の内容をファイルに出力することが可能です。
(出力先は絶対パス・フルパス両方指定可能です)
 
例えば、以下のように記述することで、Hello World! と書かれたテキストが C:\tmp\hoge.txt に出力されます。
echo Hello World!>C:\tmp\hoge.txt
 
">"の部分はリダイレクトと呼ばれており、">"と記述すれば上書きで出力、">>"と記述すれば改行して追記で出力となります。
 
なお、空ファイルを出力するには、下記のように記述すれば良いです(空の文字を入力する、という意味です)。
type nul >C:\tmp\hoge.txt
 
6.変数の利用
Windowsバッチでは変数を利用することが可能です。
 
以下は、変数を利用してHello World!を出力する例です。SETで変数を定義、%%で囲むことで変数の参照(正確には展開)が可能です。
@echo off
SET NAME=World
echo Hello %NAME%!
pause
 
例えば、実行したWindowsバッチのフルパスの取得や、システム時刻の取得で変数を使う場合が多いです。
実行したWindowsバッチのフルパスの取得は
SET hoge=%~dp0
システム時刻(YYYYMMDDHHMMSS)の取得は
SET time0=%time: =0%
SET hoge=%date:~0,4%%date:~5,2%%date:~8,2%%time0:~0,2%%time0:~3,2%%time0:~6,2%
で可能です。
 
7.IF文の制御
WindowsバッチではIF文で簡単な制御を行うことができます。
 
例えば、ファイル・フォルダの存在確認は下記のような記述で実現可能です。
IF EXIST hoge (
  echo OK
) ELSE (
  echo NG
)
 
ここで、hogehoge\ とすることで、フォルダのみの存在確認が可能になります。
hoge という名前のファイルが存在していても偽とすることができます。
また、"IF"の直後に"NOT"を繋げることで、真偽判定を逆にすることができます。
 
文字列比較も可能で、下記のように記述します。
IF %HENSU%==hoge (
  echo OK
) ELSE (
  echo NG
)
 
数値の比較も可能ですが、比較演算子として"=="の代わりに"equ"(等しい)、"neq"(等しくない)、"lss"(左辺が右辺より小さい)、"leq"(左辺が右辺以下)、"gtr"(左辺が右辺より大きい)、"geq"(左辺が右辺以上)を使うことに注意が必要です。
 
8.その他の制御
forループやcall・gotoによるジャンプ、exitでのバッチ終了も可能です。
この記事では例を1つ挙げるだけに留めますが、下記はworkフォルダの中の各々のファイルを、順番に C:\tmp\Program.exe の引数として与えて実行する例です。
for文で順番に従って"%%a"にファイル名を格納、"%%a"を第一引数としてmethodルーチンへ飛ばし、methodルーチンでは受け取った引数を C:\tmp\Program.exe の引数として与えて実行、for文が終了したら(全てのファイルに対して処理が終了したら)exitでバッチファイルを終了、ということをしています。
cd work
for %%a in (*) do (call :method %%a)
exit
:method
C:\tmp\Program.exe %1
goto :eof