LoginSignup
5
1

バッチファイルで括弧付きのファイルがstartできないときの対処法

Last updated at Posted at 2023-04-26

発生している問題

あるバッチファイルから、パス名に括弧()のあるバッチファイルをstartできない。
例) test(hoge).batfoo(new)\update.bat など。

実際のコード

解説するツリー構造は以下の通りです:

.
├── hoge.bat
└── test(hoge).bat

以下が期待通りに動作しないコードになります。

hoge.bat (呼び出す側)
start "title" "test(hoge).bat"
pause
test(hoge).bat (呼び出される側)
pause

hoge.batを開くと、新しいウィンドウは開くのですが、新しいウィンドウに次のような表示がされます。

'test' is not recognized as an internal or external command,
operable program or batch file.

原因

どうやらstartコマンドは、.batファイルや.cmdファイルを開くときに、
C:\WINDOWS\system32\cmd.exe/Kオプションと開きたいバッチファイルを引数として渡して開く挙動をするようです。

例えば、上のhoge.batなら、C:\WINDOWS\system32\cmd.exe /K "test(hoge).bat"という風な実行のされ方をします。

ここで、cmd.exeは受け取った"test(hoge).bat"(を特別な記号として解釈するので、結果的にtestだけが実行されてしまって、上のようなエラーになるようです。

解決方法1 - あきらめる

パス名に括弧()を使わないでください。 これが一番手っ取り早く、確実な方法です。

解決方法2 - callを活用する

start "title" "cmd.exe" /k call "test(hoge).bat" と書くと実行できます。
原理としては、これまでの問題はcmd.exe(を特別な記号として解釈していたからなのですが、なぜかcmd.exeが受け取る第2引数以降は(を普通の文字列として受け取るようです。それを利用して、start先でcallするという力業でどうにかなります。

解決方法3 - エスケープする

start "title" "cmd.exe" /k "test^^(hoge^^).bat" と書くと実行できます。
この方法の肝は、キャレット^を2回書くことです。こうすることで、呼び出すバッチ側が"test^(hoge^).bat"と解釈して、呼び出された側のcmd.exe(をエスケープできるので実行できます。

解決方法4 - 末尾に空白を付ける

start "title" "test(hoge).bat " と書くと実行できます。
この方法の肝は、呼び出すパスの後に空白を付けることです。cmd.exeは、なぜかパス名に空白があると、その文字列をパスとして認識し始めます。それを利用して、最後に空白を付けることで、パスとして認識させることで実行できます。

解決方法5 - ダブルクォーテーションを増やす

start "title" ""test(hoge).bat"" と書くと実行できます。
この方法の原理はわかりませんが、なぜか動きます。
この方法は、パス名に空白があると動かないので、使う際は注意して使ってください。

まとめ

cmd.exe、クソすぎる。

謝礼

質問に答えていただいた @imagou 様、 @HalHarada 様、 @mrbonjin 様ありがとうございました!

5
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
1