見出し画像

バッチファイルの「%~dp0」 の意味

結論:実行されたバッチファイルが保存されているディレクトリパス

よく見かけるコマンド

バッチファイルの先頭に以下のようなものが記述されているのをよく見かけると思います。

@echo off
cd /d %~dp0

「@echo off」はコマンド エコー機能をオフにするコマンドです。@を付けることで「@echo off」のコマンド自体も表示されないようになります。試しに@を外すと以下のようになります。

D:\>Test.bat

D:\>echo off

cdコマンドは現在のディレクトリを変更したり表示したりするコマンドです。chdirコマンドも同じです。

D:\>cd
D:\

D:\>cd Temp

D:\Temp>

dパラメータを付けることで現在のディレクトリだけでなくドライブも変更できます。以下のように「/d」を付けないとドライブが変更出来ないことが分かると思います。

D:\Temp>cd C:

D:\Temp>cd /d C:

C:\>

「%~dp0」の意味

ここから本題、「%~dp0」は変更するディレクトリ先です。バッチファイルにおいてパラメーターは「%0」「%1」「%2」...と表記できます。「%0」は実行されたバッチファイル自身のフルパスです。

例えば以下のようなバッチファイルを作成し、

@echo off
echo %%0 : %0
echo %%1 : %1

適当なファイルをバッチファイルに対してドラッグアンドドロップすると以下のように表示されます。

%0 : "D:\Test.bat"
%1 : D:\test.txt

ドラッグアンドドロップされたファイルのパスが「%1」で取得できました。「%1」と異なり「%0」のバッチファイル自身のフルパスの方は「"」で囲まれています。

これはバッチファイル自身のフルパスにスペースが入っている可能性があるからです。パスにスペースの入ったファイルをドラッグアンドドロップすると「"」で囲まれるようになります。

%1: "D:\Test Test\test.txt"

ここではバッチファイルが格納されているディレクトリのパスをcdコマンドの引数に渡したいので、ファイル名(test.bat)が邪魔ですね。「cd %0」と指定すると「ディレクトリ名が無効です。」と表示されてしまいます。

ディレクトリ名が無効です。

そこでパラメーターを指定して余計なものを除いた結果が「%~dp0」です。細かいパラメーターの一覧はMicrosoft公式で見れますが、実際にコマンドで確認してみましょう。

以下のようなバッチファイルを作成して実行してみます。

@echo off
echo %%0    : %0
echo %%~0   : %~0
echo %%~d0  : %~d0
echo %%~p0  : %~p0
echo %%~dp0 : %~dp0

結果は以下のようになったと思います。「~」だけだと「"」が除かれ、「~d」だとドライブ名が、「~p」だとパスのみ(ドライブなし)が取得できます。「~dp」と組み合わせることでバッチファイルが保管されているディレクトリのパスが取得できました。

%0    : "D:\Test.bat"
%~0   : D:\Test.bat
%~d0  : D:
%~p0  : 
%~dp0 : D:\

配置されている場所に関わらず、管理者実行すると現在のディレクトリが「C:\Windows\System32」になってしまったりするので、バッチファイルの先頭に「cd /d %~dp0」と書かれていることが多いです。

「call /?」

バッチパラメーターは前述のリンクを見に行かなくても、「call /?」で一覧を確認できます。

C:\>call /?
バッチ プログラムを別のバッチ プログラムから呼び出します。

CALL [ドライブ:][パス]ファイル名 [バッチパラメーター]

  バッチパラメーター   バッチ プログラムで必要なコマンド ライン情報を指定します。

コマンド拡張機能を有効にすると、CALL は次のように変更されます:

CALL コマンドは、CALL のターゲットとしてラベルを受け付けるようになります。
構文は、次のとおりです:

    CALL :ラベル 引数

指定された引数で新しいバッチ ファイル コンテキストが作成され、指定
されたラベルの次の文に制御が渡されます。バッチ スクリプト ファイルの
最後に 2 回到達することによって、2"終了" する必要があります。
1 回目に最後に到達したときには、制御は CALL 文の次の行に返されます。
2 回目に、バッチ スクリプトが終了します。バッチ スクリプトから "戻る"
ための GOTO :EOF 拡張機能の説明については、GOTO /? と入力してください。

また、バッチ スクリプトの引数参照 (%0、%1 など) の展開は、次のように
変更されました:


    %* バッチ スクリプト内では、すべての引数 (%1、%2、%3、%4、
        %5 など) を参照します。

    バッチ パラメーター (%n) の置換は拡張されました。次のオプション構文
    を使うことができます:

        %~1         - すべての引用句 (") を削除して、%1 を展開します。
        %~f1        - %1 を完全修飾パス名に展開します。
        %~d1        - %1 をドライブ文字だけに展開します。
        %~p1        - %1 をパスだけに展開します。
        %~n1        - %1 をファイル名だけに展開します。
        %~x1        - %1 をファイル拡張子だけに展開します。
        %~s1        - 展開されたパスは、短い名前だけを含みます。
        %~a1        - %1 をファイル属性に展開します。
        %~t1        - %1 をファイルの日付/時刻に展開します。
        %~z1        - %1 をファイルのサイズに展開します。
        %~$PATH:1   - PATH 環境変数に指定されているディレクトリを検索し、
                       最初に見つかった完全修飾名に %1 を展開します。
                       環境変数名が定義されていない場合、または
                       検索してもファイルが見つからなかった場合は、
                       この修飾子を指定すると空の文字列に展開されます。

    修飾子を組み合わせて、複合結果を得ることもできます:

        %~dp1       - %1 をドライブ文字とパスだけに展開します。
        %~nx1       - %1 をファイル名と拡張子だけに展開します。
        %~dp$PATH:1 - PATH 環境変数に指定されているディレクトリを
                       検索して %1 を探し、最初に見つかったファイル
                       のドライブ文字とパスだけに展開します。
        %~ftza1     - %1 を DIR の出力行のように展開します。

    上の例の %1 と PATH は、他の有効な値で置き換えることができ
    ます。%~ 構文は有効な引数の数によって区切られます。%~ 修飾子
    は %* と同時には使用できません。

余談:ぼっち・ざ・ろっく!

全く関係ないのですが、Amazonで「バッチファイル」と検索したら『ぼっち・ざ・ろっく!』が出てきました。バッチ・ザ・ファイル!

Amazon.co.jp : バッチファイル

出来ることが増えると記事に還元されます。コメント頂ければ参考にします。