バックアップのバッチファイルを作ってて、ログファイル名を生成する時に遭遇した事象。
Windowsバッチのパラメータ%0を参照すれば、実行しているバッチファイル名を取得することができる。
ファイル名のみを取得する場合は、Windowsバッチのパラメータの修飾子により%~n0で取得することができる。
とした時に、Windowsバッチファイル内でサブルーチンを呼び出した場合、呼び出し先のサブルーチンで取得できる値に違いがあった。
動作の違いの例
Windowsバッチファイル名(フルパス):K:\TEST\TEST.bat
呼び出し先のサブルーチン名:subroutine
参照した値 | 起動したWindowsバッチファイルのメイン | 呼び出し先のサブルーチン |
---|---|---|
%0 | K:\TEST\TEST.bat | subroutine |
%~n0 | TEST | TEST |
パラメータ%0の値が異なるのはそういう動作としたとしても、修飾子により参照した%~n0の値が同じになるのがイマイチ納得できない…
サンプルコード
サンプルコードでは、外部のバッチファイルを呼び出した時の動作も確認している。
起動元のバッチファイル:TEST.bat
echo off ver echo. echo -------- 起動元のバッチファイル -------- echo [起動元のバッチファイルのメイン] echo %0 echo %~n0 call :subroutine call %~dp0TEST_SUB pause exit /b :subroutine echo [起動元のバッチファイルのサブルーチン] echo %0 echo %~n0 exit /b
サブのバッチファイル:TEST_SUB.bat
echo off echo -------- サブのバッチファイル -------- echo [サブのバッチファイルのメイン] echo %0 echo %~n0 call :subroutine_SUB pause exit /b :subroutine_SUB echo [サブのバッチファイルのサブルーチン] echo %0 echo %~n0 exit /b
サンプルコードの実行結果
>k:\test\test.bat >echo off Microsoft Windows [Version 10.0.17134.191] -------- 起動元のバッチファイル -------- [起動元のバッチファイルのメイン] k:\test\test.bat TEST [起動元のバッチファイルのサブルーチン] :subroutine TEST -------- サブのバッチファイル -------- [サブのバッチファイルのメイン] k:\TEST\TEST_SUB TEST_SUB [サブのバッチファイルのサブルーチン] :subroutine_SUB TEST_SUB 続行するには何かキーを押してください . . .
念のための確認
起動元のバッチファイルのメインで「%~n0」を参照することで、最初に参照した値で固定されてしまうのでは?と思い、起動元のバッチファイルのメインの「echo %~n0」をコメントアウトしてみたが、呼び出し先のサブルーチンで取得できる値の結果は同じであった。
その他気が付いたこと
バッチファイルの起動方法で、パラメータ%0を参照した時の値に2点違いがあった。
「パラメータ%0がダブルクオーテーションで囲まれるかどうか」と「パスの大文字小文字」
起動方法 | 囲まれる | 大文字小文字 |
---|---|---|
エクスプローラーからダブルクリック | 〇 | エクスプローラーの見た目と同じ |
ファイル名を指定して実行 | 〇 | ファイル名指定時の文字と同じ(ドライブレターは必ず大文字) |
コマンドプロンプトで実行 | × | ファイル名指定時の文字と同じ |
バッチ内での外部バッチファイルを呼び出し | × | call文で指定した文字と同じ |
参考
コマンドプロンプトを使ってみよう! -バッチファイルとは?-
バッチパラメータ・修飾子
https://ykr414.com/dos/bat.html#05