おはようございます。くろねこです。
「バッチ特集」の 第5回 です。
今回の記事は、CALL についてです。
【ご注意】
本サイトを参考に作成したものは、自己責任でお願いします。
実行前のレビューやテストを必ず実施してください。
それでは、今回もよろしくお願いします。
CALLとは【講釈】
バッチのCALLは、一般的なプログラム言語のCALLとほぼ同じものと考えてください。
CALLは以下の二つのことができます。
・ 別のバッチファイルを呼び出す
・ バッチファイル内の一部をサブルーチンとして呼び出す
別のバッチを呼び出す【講釈】
呼び出し方法は以下の通りです。
call バッチファイル
呼び出すバッチファイルが別のフォルダに存在する場合は、そのパス名も含めて記述します。
呼び出したバッチの実行が終了するとCALLの次の命令が実行されます。
呼び出したバッチの終了コードも判断することができます。
終了コードは、ERRORLEVEL で判断します。
もう少し、掘り下げていきましょう!
呼び出し方法はほかにも
同期型(※)でのバッチの呼び出し方法は
① CALL
② START "" /WAIT /B
③ CMD /C
の何れの方法でも可能です。
※ 同期型とは、親プロセスが子プロセスを呼び出した際に、親プロセスは子プロセスの終了を待ちます。
これら3つの方法について、Windows11の環境での検証を実施しました。
あくまでも個人的な感想ですが、
やはり、扱いやすさからして、おすすめは、CALLですね。
シンプルですし、システムへの負荷も少ない(新たなプロセスを生成しない)のが
モア ベター おばちゃまぁ~(古)
そもそも、STARTコマンドは本来、非同期実行を目的としたものですので、同期実行させるのには、ちょっと手間がかかるのかもしれません。
サブルーチン【講釈】
CALLのもう一つの使い方として、バッチ内の一部をサブルーチン化することができます。
具体的には、バッチ内に記述したラベルをCALLで呼び出すことができます。
ざっくりですが、こんな感じです。
・・・ call :ラベル ・・・ exit /b :ラベル (サブルーチンでの処理) exit /b
サブルーチン化のメリットは
同じような処理をバッチ内の複数の個所で組む場合は、その処理をサブルーチンとして作成し、呼び出したほうが効率的になります。
サンプル
別のバッチ呼び出し (CALL)
@echo off rem *** Main.bat *** cd /d %~dp0 echo Main.bat Started %date% %time% echo CALL呼び出し 第1引数と第2引数をSub.batに渡します。 call .\Sub.bat %1 %2 echo Sub.bat 終了コード : %ERRORLEVEL% echo Main.bat Ended %date% %time% exit /b
上記のバッチを Main.bat で保存してください。
(※文字コードはANSIです)
@echo off rem *** Sub.bat *** cd /d %~dp0 echo Sub.bat Started %date% %time% echo 第1引数 : %1 echo 第2引数 : %2 pause echo Sub.bat Ended %date% %time% rem 終了コードは無条件に 16 とします exit /b 16
上記のバッチを Sub.bat で保存してください。保存先は Main.bat と同じフォルダです。
(※文字コードはANSIです)
コマンドプロンプトを開き、保存先フォルダをカレントフォルダにして、Main.bat を実行してみてください。
以下のように実行されます。
別のバッチ呼び出し (START)
STARTコマンドで バッチの CALL と同じ動きをさせるための方法です。
個人的な意見ですが、
STARTコマンドの(変な)仕様のため、使い方に注意が必要です。
【呼び出し元】
呼び出し元(main.bat)では、
start "" /wait /b 呼び出すバッチ [引数1 [引数2 ・・・]]
と書きます。
最初の "" はタイトル(コマンドプロンプトのタイトルバーに表示されるもの)で、省略した場合、呼び出すバッチが "" で囲まれているときに誤認するので、タイトル不要でも必ず書いた方がよいです。
/wait /b は必ず指定します。
/wait は、同期型実行で、呼び出し先の処理が終了するまで処理の実行を待ちます。
/b は、新しいウィンドウを作成せずに、呼び出し先の処理を実行します。
【呼び出し先】
呼び出し先(sub.bat)では、終了時に
exit [終了コード]
と書きます。
/b を付けると呼び出し元のバッチも一緒に終了します。
以下、サンプルです。
@echo off rem *** Main.bat *** cd /d %~dp0 echo Main.bat Started %date% %time% echo START /WAIT 呼び出し 第1引数と第2引数をSub.batに渡します。 start "" /wait /b .\Sub.bat %1 %2 echo Sub.bat 終了コード : %ERRORLEVEL% echo Main.bat Ended %date% %time% exit /b
上記のバッチを Main.bat で保存してください。
(※文字コードはANSIです)
@echo off rem *** Sub.bat *** cd /d %~dp0 echo Sub.bat Started %date% %time% echo 第1引数 : %1 echo 第2引数 : %2 pause echo Sub.bat Ended %date% %time% rem 終了コードは無条件に 32 とします exit 32
上記のバッチを Sub.bat で保存してください。保存先は Main.bat と同じフォルダです。
(※文字コードはANSIです)
コマンドプロンプトを開き、保存先フォルダをカレントフォルダにして、Main.bat を実行してみてください。
以下のように実行されます。
別のバッチ呼び出し (CMD)
CMDコマンドで バッチの CALL と同じ動きをさせるための方法です。
【呼び出し元】
呼び出し元(main.bat)では、
cmd /c 呼び出すバッチ [引数1 [引数2 ・・・]]
と書きます。
【呼び出し先】
呼び出し先(sub.bat)では、終了時に
exit [/b] [終了コード]
と書きます。
/b は書いても省略しても同じ動きをします。
以下、サンプルです。
@echo off rem *** Main.bat *** cd /d %~dp0 echo Main.bat Started %date% %time% echo CMD /C 呼び出し 第1引数と第2引数をSub.batに渡します。 cmd /c .\Sub.bat %1 %2 echo Sub.bat 終了コード : %ERRORLEVEL% echo Main.bat Ended %date% %time% exit /b
上記のバッチを Main.bat で保存してください。
(※文字コードはANSIです)
@echo off rem *** Sub.bat *** cd /d %~dp0 echo Sub.bat Started %date% %time% echo 第1引数 : %1 echo 第2引数 : %2 pause echo Sub.bat Ended %date% %time% rem 終了コードは無条件に 64 とします rem exit 64 exit /b 64
上記のバッチを Sub.bat で保存してください。保存先は Main.bat と同じフォルダです。
(※文字コードはANSIです)
コマンドプロンプトを開き、保存先フォルダをカレントフォルダにして、Main.bat を実行してみてください。
以下のように実行されます。
サブルーチン呼び出し (基本形)
バッチの一部をサブルーチンとして利用する場合は以下のようにバッチを作ります。
・・・ call :ラベル [引数1 [引数2 ・・・]] (errorlevelで終了コードを取得) ・・・ exit /b [メインの終了コード] :ラベル (サブルーチンの処理) exit /b [サブルーチンの終了コード]
サブルーチンで引数を受け取る場合は、%1、%2・・・とバッチの引数と同じように受け取ることができます。
呼び出し元(メインルーチン)の引数とサブルーチンの引数は同じ %1 ・・・ と表現しますが、
それぞれの変数の領域は異なるものですので
・ メインルーチンの%1
・ サブルーチンの%1
という風に考えてください。
サブルーチンの終了部分はバッチ同様に exit で終了コードを呼び出し元に返すことができます。
以下、サンプルです。
@echo off rem *** Main.bat *** cd /d %~dp0 echo Main.bat Started %date% %time% echo 第1引数 : %1 echo 第2引数 : %2 echo サブルーチン呼び出し 第1引数と第2引数を加算した結果を引数にします。 set /a @param=%1+%2 call :sub %@param% echo サブルーチンの終了コード : %ERRORLEVEL% echo 第1引数 : %1 echo 第2引数 : %2 echo Main.bat Ended %date% %time% exit /b :sub rem *** Subroutine *** echo Subroutine Started %date% %time% echo 第1引数 : %1 echo 第2引数 : %2 echo 第1引数の数値を 10倍して戻り値とします。 pause set /a @ans=%1*10 echo Subroutine Ended %date% %time% exit /b %@ans%
上記のバッチを Main.bat で保存してください。
(※文字コードはANSIです)
コマンドプロンプトを開き、保存先フォルダをカレントフォルダにして、Main.bat を実行してみてください。(引数1=10、引数2=5)
以下のように実行されます。
サブルーチン呼び出し (ちょっと応用:引数分解)
呼び出し元(メインルーチン)から、サブルーチンを呼び出す際にスペースを含んだ文字列を指定すると スペースで分離された文字列がサブルーチンに渡されます。
(まあ、あたりまえですね)
以下、サンプルです。
@echo off rem *** Main.bat *** cd /d %~dp0 echo Main.bat Started %date% %time% set @string=abcd 1234 efgh 5678 echo サブルーチン呼び出し スペースを含んだ文字列を引数にします。 call :sub %@string% echo サブルーチンの終了コード : %ERRORLEVEL% echo Main.bat Ended %date% %time% exit /b :sub rem *** Subroutine *** echo Subroutine Started %date% %time% echo 第1引数 : %1 echo 第2引数 : %2 echo 第3引数 : %3 echo 第4引数 : %4 pause echo Subroutine Ended %date% %time% exit /b 0
上記のバッチを Main.bat で保存してください。
(※文字コードはANSIです)
コマンドプロンプトを開き、保存先フォルダをカレントフォルダにして、Main.bat を実行してみてください。(引数1=10、引数2=5)
以下のように実行されます。
おわりに
なかなか説明が難しく、全体的に講釈っぽくなってしまいました。すいません。
バッチを作成した方なら、サンプル部分を見ていただくことで、動きが理解できると思います。
念のため、これらのサンプルはWindows11で検証したものです。
まだまだ、バグが多いWindows11ですが、バッチは何とか動くようです(笑)
それでは
バッチ特集の過去の記事は下記をクリック願います。