注意: この記事は次の環境で確認を行いました。
- Microsoft Windows 10 Pro Edition
- OpenJDK 11
- Eclipse 2019-09 (Pleiades All in One)
C:\sample
というフォルダにhelloworld.bat
が設置されているとします。内容は次の通りです。
@echo off
echo Hello World 01
echo Hello World 02
echo Hello World 03
このhelloworld.bat
をJavaから実行するサンプルが以下になります。
// ProcessBuilderの生成
// helloworld.batのstdinとstderrを親プロセスのstdinとstderrにつなぐ。
var processBuilder = new ProcessBuilder("C:\\sample\\helloworld.bat");
processBuilder.redirectOutput(ProcessBuilder.Redirect.INHERIT);
processBuilder.redirectError(ProcessBuilder.Redirect.INHERIT);
// Processの生成
// helloworld.batを子プロセスとして実行し、プロセス実行が終わるまで親スレッドを停止する。
var process = processBuilder.start();
process.waitFor();
これを実行すると、次のような文字列がJavaの標準出力に出力されているはずです。
Hello World 01
Hello World 02
Hello World 03
個人的に「はまった」ポイントとしては、バッチファイルの拡張子。実行したいファイルの拡張子はbatまたはcmdである必要があります。
いわゆるシェルスクリプトの世界では、スクリプトが記述されたファイルの拡張子に指定はありません。慣習的にsh
とすることが多いと思いますが、実行権限さえ付与されていれば、txt
でもhtml
でも実行可能ですし、拡張子がなくても問題ありません。
一方、Windowsの世界では、そのファイルがバッチファイルかどうかを判定するにあたって、拡張子を利用しています。つまり拡張子がbatもしくはcmdの場合、そのファイルを実行可能なバッチファイルとみなすわけです。
自分がはまっていたのは「拡張子batでもcmdでもないファイルをProcessBuider
やProcess
で実行しようとして、うまくいかない」というところでした。わたしはいわゆるオープン系のアプリケーション開発者です。その世界(つまりLinuxやUnix)では実行権限が正しく付与されていれば、拡張子のいかんを問わず実行できてしまうわけで、「特定の拡張子を指定する必要がある」という発想になかなかいたりませんでした(´・ω・`)