ITエンジニアの成長ブログ

ITエンジニアとして行う勉強の発信&日々の生活で体験した楽しいことをゆるく発信

Windowsのバッチファイルから別バッチファイルを呼び出したときの挙動について

今回は、Windowsのバッチファイルについてのある挙動についてメモ程度に残しておこうと思います。

Javaのビルドツールである、Apache Antを使用してビルドをしていたときのことでした。
かなり簡略した形ですが、以下のようにantを実行する処理をバッチファイルに組み込んでいました。

@echo off

echo test.batを開始します。

ant -Dmsg=aiueo

echo test.batを終了します。


こちらも簡略したものですが、antの設定ファイルである、build.xmlは以下であったとします。

<project name="MyProject" basedir=".">
	<echo message="msg = ${msg}"/>
</project>


コマンドプロンプトで上記のバッチを実行してみると以下のようになりました。

バッチファイル実行結果1


なんと、バッチファイルの最後のechoコマンドの処理が実行されていないのです。

「ant」は実はバッチファイルなのですが(ant.bat)、バッチファイルから別バッチファイルをそのまま呼び出すことで(バッチファイル名をそのまま命令)、別バッチファイルの呼び出し部分を実行した後にそのままバッチが終了してしまうようです。

そのため、今回は別バッチファイルの呼び出しの後に記載されているechoコマンドが処理されないということになってしまっています。

この挙動は知りませんでしたが、今回のようにバッチファイルで別バッチファイルを単純にファイル名で呼び出すことで、その部分で処理が終わってしまうのは、どうやらネットで調べてみるとそのような仕様(?)のようです。

このようなバッチの挙動は多くのケースでは想定していないと思います。別バッチファイルを実行した後は、元のバッチファイルの後続の処理が実行されてほしいと思うのが通常のケースだと思います。

この挙動を避けるためには、antの実行時に「call」を付与することで対応できます。対応したバージョンのバッチファイルは以下の通りです。

@echo off

echo test.batを開始します。

call ant -Dmsg=aiueo

echo test.batを終了します。

もう一度、実行してみましょう。今度はちゃんと、バッチファイルがすべて実行されました。

バッチファイル実行結果2

バッチファイルの前に付与されている「call」は他のバッチファイルを呼び出すためのコマンドです。他にも「start」というコマンドがありますが、今回は「call」と「start」コマンドの違いなどには特に触れないことにします。

あと、もう一つ補足として「exit」コマンドを仮に子バッチの方に「/b」オプションありで実行した場合にも、callで子バッチを呼び出さないと親バッチがそこで終了してしまいます。

以下は「exit」コマンドの「help」を表示したものです。「/b」オプションは”CMD.EXE ではなく、現在のバッチ スクリプトを終了するように指定します。”と記載されているので、callなしでも問題ないかなと考えてしまいましたが、どうやらそうではないようです。

exitのhelp表示

結論からは、多くのケースでは他バッチを実行する場合は「call」を付与してあげることが良さそうです。
最近ではPowerSellを使用したりと、バッチファイルをあまり触る機会は少ないかもしれませんが、いつかのためにこのような細かい挙動を頭の片隅にでも入れておきたいなと思います。

今回はこの辺で失礼いたします。最後までお読みいただきありがとうございました。