第4回 スクリプト入門(その2):Windows 2000 活用講座 Windows 2000 コマンドライン徹底活用(2/2 ページ)
今回は、状況に応じた動作を可能にするために条件判断と組み合わせて使用される「ジャンプ」にスポットをあてる。
ジャンプの1種として、「サブルーチン・ジャンプ」というものもある。これは、1回ジャンプを行って、その先のコマンドを実行した後、ジャンプ元の次の行に復帰するという動作を行うものだ。
プログラム中には、似たような処理や同じ処理を複数のスクリプトで使う場合がある。このような場合にサブルーチンを作成し、必要に応じて呼び出して使えると便利である。これを実現するのがサブルーチン・ジャンプである。
Windows 2000のスクリプト言語では、“call”コマンドを使う。このコマンドは、スクリプト内のサブルーチン・ジャンプと、別ファイルになったスクリプトの呼び出しを兼ねている。
スクリプト・ファイル内でのcallコマンドの動作は、以下のようなものになる。
callコマンドにラベルが指定された場合、通常のgotoコマンドのようにラベルが検索され、そこに実行の制御が移る((1))。その後、処理を実行して、プログラム末(スクリプト・ファイルの最後)に到達したら、制御は、そのサブルーチンを呼び出したcallステートメントの直後に戻る((2))。なお、callステートメントによるサブルーチン呼び出しを行わずにスクリプト・ファイルの最後に到達したら、スクリプトの実行は終了する。
なお複数のサブルーチンを使う場合、「プログラムの終わり」は、スクリプト・ファイルに1つしかないため、“goto :EOF”ステートメントを最後に置いて、プログラムの最後へ移動させる。見かけ上は、callに対する戻りのステートメントとして“goto :EOF”を使うことができる。つまり、
サブルーチンが呼び出され((1))、処理が終わったら、そこにある“goto :EOF”によってプログラムの最後へ飛び((2))、その結果サブルーチンの実行が終了して、呼び出し元のcallステートメントの次の行へ制御が戻る((3))わけである。
多くのプログラム言語では、callと対になるreturnなどのステートメントを用意しているが、このバッチ・コマンドでは、プログラムの最後で、それまでの過程により動作が変わるような仕組みとなっている。なぜこのようになっているのかは不明だが、Windows NTより以前のOSでは、ラベルによるスクリプト内のサブルーチン呼び出しはできず、単に別のスクリプト・ファイルを呼び出して、実行後に元の位置に復帰するだけであった。推測ではあるが、おそらく、DOS時代から作られてきたスクリプト(バッチ)処理ルーチンのソースを改造することで、Windows 9x、Windows NTのスクリプト処理ルーチン(あるいはcmd.exe)が作られてきており、Windows 2000のcmd.exeもこれを最小限の手間で改造する形で作られているため(もしくは互換性を完全にするため)、このような奇妙な形になったのではないかと思われる。
callステートメントでは、引数を指定したり、別のスクリプト・ファイルなどを呼び出したりすることが可能であり、また、呼び出し先のサブルーチンは、同一スクリプト・ファイル内であっても、新たに実行環境が作られて実行される(環境変数の継承などに違いが出る)などの複雑な機能を持つため、また別途詳しく解説することにしたい。ここでは、サブルーチンを作成するなら、callステートメントが利用可能であるという程度の認識でかまわないだろう。なぜなら、コマンドプロンプト・スクリプトで、サブルーチンを多用するような大規模なファイルを作成することは不可能ではないが、あまり効率的でもない。デバッグなどの効率を考えると、WSH(Windows Scripting Host)やVisual BASIC、Perlなどの利用を考えたほうがいいだろう。
callコマンドは、本来、別スクリプト・ファイルを呼び出すために作られたものであるが(MS-DOSやWindows 9xではこのような使い方しかできない)、Windows 2000では、上記のように同一スクリプト・ファイル内でのサブルーチン・ジャンプが可能なように機能が拡張されている。この2つはスクリプトからみるとほぼ同等だが、別スクリプト・ファイルを呼び出すものは、複数のスクリプト・ファイルでサブルーチンを共有することが可能になるというメリットがある反面、呼び出しのオーバーヘッドがかかること(別スクリプト・ファイルの呼び出し)、エラー処理が煩雑になること(サブルーチン内では、呼び出し元の状況がまったく分からないし、エラー結果を呼び出し元に返すのも難しい)、スクリプト自体の管理が面倒になること(複数ファイルを扱うことと、修正時に呼び出しを行うすべてのスクリプトとの整合性を確認する必要がある)といったデメリットがある。これに対して、同一スクリプト内でのcallステートメントによるサブルーチン呼び出しは、オーバーヘッド、ファイル管理の点ではラクになるが、複数スクリプト間で同一のサブルーチンを共有することができない(必要ならば、同じコードをすべてのスクリプト・ファイルにコピーすることは可能)。とはいえ、作成したサブルーチンを複数のスクリプト・ファイルで共有する可能性がないのなら、わざわざ別のファイルに分ける必要はなく、同じスクリプト・ファイル内におくだけで十分だろう。
今回のまとめ
- 制御の流れを変えるには、gotoステートメントを利用する。
- ジャンプ先のラベルは、行に先頭に“:”を付けて記述する。
- スクリプト・ファイルの動作を終了させるには、特別なラベル“:EOF”へジャンプする。
- 飛び先ラベルに環境変数を組み合わせると、間接的なジャンプを実現することができる。
- サブルーチン呼び出しを行なうには、callステートメントを使う。
- callの飛び先には、別のスクリプト・ファイルを指定するか、ラベルを指定することができる。
Copyright© Digital Advantage Corp. All Rights Reserved.