キレない関数(サブルーチン)の作り方~バッチファイル編~
はじめましての方は、初めまして
ご存知の方は、そうだよヒズミさんだよ
今回は、みんな大好きバッチファイルの話だよ。
バッチファイルは、IFやFORといった制御構文を持ち、変数による値の保持ができます。
そのため、ただ、コマンドを羅列するだけではなく、ある程度のスクリプトを書くことができます。
ただし、やや癖があるので、ほかの言語と同じ感覚でうっかりサクッと手を出すと、簡単にハマります。
ストレスで毛根がマッハで抜けます。
そうならないための記事の序章がこちら
バッチファイルの関数について
概要みたいなもん
バッチファイルは、前述の通り、IFやFORの制御構文の他に、関数のようなものを宣言することができます。 スクリプトの中で、再利用する処理をまとめることができます。 実際は、ジャンプ先の目印をつけるだけのラベルというのですが、ここでは、便宜上、関数と呼称します。
宣言の仕方
:sayHello echo Hello, world exit /b
コロン(:)の後に、名前を記述して改行することで、宣言したことになります。
bashスクリプトを書いたことある人は、以下の様に、functionの接頭辞をつけたと思いますが、
前述の通り、ジャンプする行の目印をつけているだけなので、名前だけで十分です。
呼び出し元に戻るには、exit /b
を使います。
/bはオプションなので、/b無しのexitと記述しても構文どおりでエラーは起きません。
その代わり、コマンドプロンプト自体が終了します。
function hogehoge(){ echo hogehoge }
呼び出し方
宣言した関数の呼び出し方は、以下のように、callの引数に関数名を指定すると、呼び出すことができます。
call :sayHello exit /b :sayHello echo Hello, world exit /b
関数に対して、引数を渡す場合は、CLIアプリケーションに引数を渡すように関数名の後ろに半角スペースをつけるだけです。
call :say HelloTaro exit /b :say echo %1 exit /b
gotoとの違い
似たようなコマンドに、指定の箇所に飛ぶ gotoというものがあります。
どちらも指定ラベルにジャンプするコマンドですが 関数として、指定ラベル先にジャンプするcallと違い、gotoは指定ラベル先にジャンプした後、呼び出し元に戻ることはありません。
関数として呼んだわけではないので、引数を指定しても渡されることもありません。
goto :say HelloTaro echo hogehoge exit /b :say echo %1 exit /b
実行結果
戻り値
実際のところ、関数ではないので、戻り値も何もありませんが・・・
call で呼び出した場合、exit /b の後に終了時の状態を数値で返すことができます。
CLIアプリケーションを使ったことある人は、0とか1とかコマンド実行後に返されると思います。
それを自分で決めることができます。バッチファイルの外に出すなら、連携のことも考えて、0か1を返すのが無難ですが、バッチファイルの中ならマイルールで返しても、大丈夫です。
関数が返した数値は、ERRORLEVEL変数で、参照できます。
@echo off CALL :say helloTaro echo %ERRORLEVEL% exit /b :say echo %1 exit /b 5
実行結果
関数内でローカル変数を宣言する
関数内に限った話ではないのですが。 バッチファイルは、基本的に宣言した変数はグローバルです。 しかし、setlocalコマンドを使うと、それ以降の行はendlocalコマンドを使うまでローカル変数扱いになります。
@echo off setlocal set hoge=fugafuga rem fugafugaが表示される。 echo %hoge% endlocal rem 外なので、表示されない echo %hoge%
注意
他の言語と違い、あくまでもジャンプ先の目印をつけただけなので、工夫しないと関数の中の処理も行ってしまうので、注意してください。
rem こう書くと、echo hogehogeを実行する前に、終了する。 :sayHello echo Hello, world rem ここで、処理が終わる exit /b echo hogehoge
rem こう書くと、echo hogehogeとecho Hello,worldを実行する echo hogehoge rem 処理は終了していないので、これ以降の処理が実行される。 :sayHello echo Hello, world exit /b
rem こう書くと、echo hogehogeだけを実行する echo hogehoge exit /b :sayHello echo Hello, world exit /b