仕事でよく使うWindowsバッチファイルのあれこれ

怪しい記事ではありません。よく使うバッチの書き方など。


お盆休みです。
仕事のトラブル?みんな忘れてしまえ〜☆(ゝω・)vキャピ
暑さが続き、朦朧とした頭の周りを、甘い言葉を囁く妖精が飛び回る夕暮れ。

そろそろ買い物にでも行こうと思うのですが、そんな私のココロとは正反対に、火照ったカラダは冷房を求め、繰り返す快楽の波に溺れるうちに、私は堕落させられていくのです。ハァハァ。

さて、、、買い物に行く前に、今回は、仕事でよく使うバッチファイルのコマンドや書き方等を自分用にまとめたいと思います。


バッチファイルのあるディレクトリに移動する

例えば、バッチファイルとexeを合わせて配布し、バッチファイルはそのexeを呼び出すものとします。
バッチ内にフルパスでexeの場所を書いてしまうと、バッチとexeの置く場所を変更した場合に悲しいことが起きてしまいます。
フルパスで書くなんて、そんなはしたないことしませんわ、とお思いの方もいるかもしれませんが、けっこう「このディレクトリにおいてください」というバッチを見るんです。

rem exeのある場所に移動!!
cd /d C:\hogehoge\fugafuga
piyopiyo.exe

バッチの最初で、下記のように書くと、バッチのあるディレクトリに移動してくれるので、後は相対パスで記述すればOKです。

cd /d %~dp0

/d はドライブ間の移動があるときのオプションですね。
%~dp0は、いつもよくわからないまま使っていましたが、バッチのフルパスを表す%0の引数にオプションをつけたものだそうです。
何とも奇怪ですね。

~は引用句(")の削除を表し、dはドライブ名、pはパス名を表すので、%0からファイル名と拡張子を除いたものになるということです。
ちなみに、nがファイル名、xが拡張子を表します。
ここまでをまとめたのが、以下の表です。

引数に使用されるオプション
オプション 意味
%n (n:0~9) 引数が入る特殊な変数。Cで言うargv[n]のようなもの。スペース等が入っていることもあるので引用句(")で囲まれている。
~ 引用句(")を削除する。
d ドライブ名だけ抽出。
p パス名だけ抽出。
n ファイル名だけ抽出。
x 拡張子だけ抽出。

コマンドを非表示にする

コマンドプロンプトに、表示させたい文字列以外が表示されてしまうと、見にくいし、カッコ悪いです。
下記のようにすると、以降のコマンドはコマンドプロンプトに表示されなくなります。

@echo off

@をコマンドの頭につけるとそのコマンドは非表示になります。
また、echo offをつけると、それ以降のコマンドは非表示になります。
単にecho offとだけ記述すると、それ以降は非表示になりますが、echo offというコマンドは表示されてしまうので、@をつけてそれ自体も表示されないようにします。


ループ処理

for文等もあるのですが、私はいつもラベルとgotoを使用しています。
下記は何かの処理を100回実行する例です。

set /a i=0
set /a max=100

:loop_start
    if %i% gtr %max% goto loop_end
    rem 何かの処理
    set /a i+=1
    goto loop_start
:loop_end
exit

ついでに、バッチの比較演算子をまとめておきましょう。
数値の比較は以下の演算子で行います。

数値比較演算子
演算子 意味
equ 等しい
neq 等しくない
lss より小さい( < )
leq 以下( <= )
gtr より大きい( > )
geq 以上( >= )

ディレクトリを作成する

ディレクトリを作成するときに、同名のディレクトリが存在するか確認してから作成します。
existを使います。

set dirname=test
if not exist %dirname% (mkdir %dirname%)

実行したコマンドの結果を取得する

実行したコマンドの結果を参照して、処理を分岐させたいことなどがあると思います。 簡単そうですが、バッチではなかなか複雑で、忘れがちです。
結果から書くと、下記のように記述します。

set result=
for /f %%i in ('hogehoge.exe') do set result=%%i

/fオプションはfor文でファイル解析を行うオプションです。
for文でシングルクォート(')で囲まれたコマンドを実行した結果をiに格納します。
そして、doで変数resultに代入しています。

この結果をif等で利用すれば、コマンドの結果により、処理を切り替えられます。
私の場合は、何らかの期待値と比較するexeを作成して、例えば、以下のように、結果をパイプでfindに渡し、"ERROR"という文字列が含まれるかどうかを調べます。
resultが空のままであればOK、何か入っていればNGとなります。

set result=
for /f %%i in ('hogehoge.exe ^| find "ERROR"') do set result=%%i
if "result"=="" (
    echo OKの処理
) else (
    echo NGの処理
)

また、下記のように、"usebackq"オプションを使用すれば、コマンドをバッククォート(`)で囲むこともできます。

set result=
for /f "usebackq" %%i in (`hogehoge.exe`) do set result=%%i

指定した秒数待つ

timeoutを使います。引数で指定した秒数、処理を停止します。

timeout 100

実行すると、残りの時間が表示されるのですが、何も表示させたくない場合は下記のようにnulデバイスにリダイレクトします。
timeout 100 > nul


シャットダウンする

shutdownを使います。

以下のように書くと、直ちにシャットダウンが開始されます。

shutdown -s -t 0

シャットダウンをする時間を遅らせたい場合は、-tの後の0を変更します。単位は秒です。

リブートする場合は、-sを-rに変えます。

shutdown -r -t 0

バッチから別のバッチを実行する(同一ウィンドウ)

callを使います。
callを使用しないで、hogehoge.batとだけ記述すると、そこで呼び出し元のバッチファイルの処理が終了してしまいます。

call hogehoge.bat

バッチから別のバッチを実行する(別ウィンドウ)

startを使います。
新しいウィンドウが開き、呼び出したバッチの処理は、そこで実行されます。
並列処理をさせたい場合に便利。

start hogehoge.bat

新しいウィンドウを表示させたくない(バックグラウンドでの処理としたい)場合、/bオプションをつけます。

start /b hogehoge.bat

ただし、バックグラウンドで開始させてしまうと、終了にはタスクマネージャー等でプロセスを終了させるしかなくなります。


さて、だいたいこんなところでしょうか。
また思い出したら随時書き足していきたいと思います。
最近はpowershellなんてものもあるので、複雑な処理が書きたかったらそっちでやった方がカンタンですね。
それでは、買い物に行ってきます。

Comments