指令本部:IBM iでのコマンド作成入門
自分のコマンドを作成し、さらに効率が高いプログラミングを目指す
System/38 の時代から、IBM i サーバー・ファミリーのコマンド・ラインと構造は、プラットフォームを問わず最高レベルでした。Unix と Linux のコマンド・ラインは、再帰的出力には -R、長形式出力には -l などとスイッチを記憶しなければならないのに対して、我々が敬愛する i システムのコマンドは、使用できるパラメーターと特殊値をすべて一緒にプロンプト表示できるのです。これらのコマンドは、2 つのパラメーターに互換性がないかどうか、またヘルプ・テキストを備えているかどうかも通知してくれます。(ほとんどの場合) 3 文字形式のコマンド頭字語 (WRKJOB や CHGOBJAUT など) は分かりやすく、覚えるのも簡単です。
しかし System i ユーザーは、IBM コマンドやベンダーによって作成されたコマンドのみに縛られる必要はありません。自分で自分のコマンドを作成できるのです。コマンドの作成は通常、単に呼び出すプログラムを作成するよりはるかに望ましく、極めて簡単です。直接プログラム呼び出しはエラーになり、変数値が互いに上書きされる傾向があります。また、ユーザーはパラメーターと有効な値の順序を覚えていなければなりません。
コマンドによりユーザーは、パラメーターは何か、パラメーターで指定できる特殊値を認識でき、とりわけ、プログラムをクラッシュさせるようなパラメーターの入力を回避できます。また、呼び出されているパラメーターの順序を覚えている必要がなくなります。ヘルプ・テキストを追加すれば、IBM で提供されているコマンドのように磨きがかかったコマンドが出来上がります。
またコマンドは、パラメーター・レベルでヘルプ・テキストを指定できます。Create Physical File (CRTPF) を使用しているプログラマーは F1 キーを叩くだけで、Reuse Deleted Records (REUSEDLT) パラメーターや Coded Character Set ID (CCSID) パラメーターの説明を読むことができます。
コマンドを検討する
プログラム呼び出しやメニュー・オプションで間に合うのに、なぜコマンドを作成するのでしょうか。それは、コマンドは柔軟性があり、特に、頻繁にタスクを実行するときなどすぐに使えるからです。
例を挙げると、BRMS は製品を管理するための完全なメニュー・システムを備えていますが、多数のメニュー・オプションの後ろにあるのはコマンドです。IBM i 6.1 時点で BRMS には 80 個を超えるコマンドがあります。期限切れのメディアを見るのにメニュー・オプションを 3 つも通りたくないでしょう。アプリケーション向けに自分のコマンドを作成することも検討しましょう。まず、アプリケーションのコマンドを作成して、それらのコマンドをメニューに追加することをお勧めするのは、理にかなっていますでしょうか。コマンドは CL プログラムでも使用できるため、自分のコマンドを持っていることは、メニュー・オプションしか使用しないアプリケーションには大きなメリットになります。
次のような場合、新しくコマンドを作成することを検討するべきです。
- プログラムを汎用ツールとして使用できる (ディスプレイ・デバイスの IP アドレス取得など)。
- 関数をコマンド・ラインや PDM ユーザー定義オプションなど他のツール内ですぐに使用できるようにしたい。
- プログラムを対話式に呼び出す必要がある。コマンドを使用すると、誤ったパラメーターを指定しないようにする場合に役立つ。
- プログラマー、オペレーター、またはユーザー向けに System ユーティリティー関数を作成中である。
- プログラムでパラメーターを複数組み合わせる必要がある。
- パラメーターのデフォルト値を使用する。
- ある環境 (対話式、バッチなど) でのみプログラムを実行する必要がある。
- 選択的なプロンプト表示でユーザビリティーを改善する。
- 機能制限されたプロファイルが特定の関数を実行できるようにする。コマンド作成時に ALWMLTUSR(*YES) を指定できる。
コマンド名を選ぶ
IBM はコマンド名に制限を設けていませんが、IBM が使用する命名規則は、どれから動作させるかについて確固たる基礎になっています。System i ユーザーなら、CVTFRMPF は物理ファイルから別の形式へ変換を行うコマンドであることが容易にわかると思います。
もちろん、IBM の命名規則を使用しなければならないわけではありません。ENABLE というコマンドを作成して、ヘルプ・デスクやサポート要員にユーザー・プロファイルを有効にするコマンドを提供できます。しかし IBM 命名規則を使用すれば、ユーザーはコマンドを忘れることなく、また見つけることもできます。
コマンド部分を特定する
ほとんどのコマンドにはパラメーターがありますが、これさえ必要ありません。パラメーターがないコマンドはシンプルです。Change Password (CHGPWD) コマンドがその例です。
コマンドで必要な部分は次の 2 つしかありません。
- コマンド定義 (これは、コマンド・ソース・コードで定義されたコマンドです)
- コマンド処理プログラム、つまり CPP (コマンドが実行するプログラム)
次のような、他のコマンド・オプションを見てみましょう。
- コマンドを実行できる場所
- ヘルプ・パネル
- プロダクト・ライブラリー
コマンド・ソース・フォーマットを作成する
コマンドは、コマンド・ソース・コードで定義されます。通常のソース・ファイル名は QCMDSRC です。例えば、CMDLIB ライブラリーで QCMDSRC ソース・ファイルを使用します。CL コマンド・ソース・コードのソース・タイプは CMD です。
下の例は、新しいコマンド DSPDEVIP (Display Device IP Address) のコマンド・ソース・コードです。DSPDEVIP コマンドのコードは System iNetwork code site からダウンロードできます。このコマンドは、デバイス名の入力パラメーターを受け取ります。関連するプログラムがデバイスの IP アドレスを決定し、デバイスの現在の IP アドレスを示すメッセージをユーザーに送信します。
CMD PROMPT('Display Device IP Address')
PARM KWD(DEVD) TYPE(*NAME) LEN(10) PROMPT('Device +
description')
DEVD パラメーターのタイプは *NAME である点に注目してください。これにより、IBM i オブジェクトの有効な名前への入力が制限されます。これで、有効なデバイス名ではない *DSP024 などのパラメーターを入力することがなくなります。コマンド・パラメーターで入力として有効な名前が必要な場合は必ず、TYPE *NAME、*SNAME、または *CNAME を使用します。自分の用途に合ったものを決める場合は、PARM コマンドのヘルプ・テキスト (F1) を参照してください。有効な名前が必要な場合は TYPE *CHAR は使用しないでください。使用すると、ユーザー・ランタイム・コマンド・エラーになります。
コマンドは次のように実行します。
DSPDEVIP DEVD(DSP024)
次を使用してコマンドを作成します。
CRTCMD CMD(CMDLIB/DSPDEVIP) PGM(DSPDEVIP)
HLPPNLGRP(DSPDEVIP) HLPID(DSPDEVIP) PRDLIB(CMDLIB)
私の場合ヘルプ・テキストは後で作成しますが、今ここで指定しても問題はありません。コマンドのプロンプトを出すと、デバイスの IP アドレスを入力するプロンプトが表示されます (図 1)。
図 2 には Command Processing Program (CPP) DSPDEVIP の CL ソース・コードが入っています。CPP のパラメーターは、コマンド定義ソース・コードのパラメーターの順番と一致している必要があります。プログラムにより、デバイスの IP アドレスを示すメッセージがユーザーに送信されます。しかし、IP アドレスを表示するのではなく CL 変数に戻したい場合はどうするのでしょうか。新しいコマンドを作成し、パラメーターを追加して値を戻すことができます。
図 3 は RTVDEVIP (Retrieve Device IP) コマンドのコマンド・ソース・コードを示しています。RTVDEVIP コマンドのコードは、System iNetwork code site からダウンロードできます。この定義では、戻された IP アドレスの第 2 パラメーターを追加しています。RTNVAL パラメーターは、値が CL 変数に戻されるよう指定します。したがって、RTVDEVIP コマンドを CL プログラムで使用する場合、次のように IPADDRESS パラメーターが IP アドレスを受信する変数名になります。
RTVDEVIP DEVD(DSP01) IPADDRESS(&IPADDR)
図 4 は RTVDEVIP プログラムの CL ソース・コードを示します。コマンドを作成するには、次のようにします。
RTCMD CMD(CMDLIB/RTVDEVIP) PGM(RTVDEVIP)
SRCFILE(CMDLIB/QCMDSRC) ALLOW(*IPGM *BPGM)
ALLOW パラメーターは、このコマンドが対話式 (*IPGM) プログラムまたはバッチ (*BPGM) プログラムでのみ使用できることを指定します。戻り変数が必要なため、このコマンドはコマンド・ラインからは実行できません。
図 5 は RTVDEVIP コマンド・プロンプトを示します。このコマンドを対話式にプロンプト表示すると、「Command RTVDEVIP not allowed in this setting (この設定では RTVDEVIP コマンドは許可されていません)」というメッセージが戻ります。コマンドは CL 変数 IPADDRESS を戻しているため、プログラム内で使用する必要があります。RTVJOBA (Retrieve Job Attribute) など他のリトリーブ・コマンドも要件は同じです。
コマンド・ヘルプを追加する
User Interface Manager (UIM) ヘルプ画面を作成する場合、UIM パネル・ソースを QPNLSRC という名前のソース・ファイルに配置します。このソース・ファイルをライブラリーに作成します。
コマンド・ヘルプの作成を支援するため、GENCMDDOC コマンドはコマンド定義をレビューし、UIM ヘルプ・テキストのテンプレートが入ったソース・ファイル・メンバーを作成します。生成された出力が、コマンド・パラメーターに基づいてヘルプ・テキスト・テンプレートになります。コマンド・ヘルプ・テキスト・テンプレートを作成するには、次のコマンドを使用します。
GENCMDDOC CMD(CMDLIB/DSPDEVIP)
TODIR('/QSYS.LIB/CMDLIB.LIB/QPNLSRC.FILE')
GENOPT(*UIM *SHOWCHOICEPGMVAL)
GENCMDDOC コマンドが完了すると、自分の要件に合うように UIM パネル・ソース・コードを変更し、Help Panel Group を作成します。ヘルプ・パネル・ソース・コードを変更するには、SEU または別のソース編集ツールを使用します。次のような行が現れるまで UIM ソース・コードを読み進めます。
* Help for parameter DEVD.
その後、次のような行が現れます。
:p.Specifies <...>
Specifies <...> というセクションを置き換えます。
デバイス記述の名前を指定します。
次に、以下のコマンドを使用して Help Panel Group オブジェクトを作成します。
CRTPNLGRP PNLGRP(CMDLIB/DSPDEVIP)
SRCFILE(CMDLIB/QPNLSRC)
コマンドのプロンプトを出し、DEVD パラメーターのヘルプを使用すると、次のヘルプ・テキストが表示されます。自分のコマンドを作成し、パネル・グループを作成する前にヘルプのパネル・グループを指定できます。パネル・グループがまだ作成されていないときに F1=Help を押すと「Help information is not available (ヘルプ情報が利用できません)」というメッセージが表示されますが、これはコマンドの実行には影響ありません。
プロダクト・ライブラリー・パラメーターを指定する
おそらく、アプリケーションを作成したとき、アプリケーションが使用するオブジェクトが入ったライブラリーが、システムやユーザー・ライブラリー・リストにない場合があるでしょう。そのライブラリーをジョブのライブラリー・リストに追加するよう要求するよりは、CRTCMD (Create Command) プロダクト・ライブラリー・パラメーターを指定します。
自分のコマンドを QGPL などのライブラリー・リストのシステム部分にあるライブラリーに配置できます。PRDLIB パラメーターを使用すると、コマンドは実行しながら、そのライブラリーにコマンドが使用するオブジェクトがあるかどうか検索しますが、プロダクト・ライブラリーはコマンド実行中にのみ使用されます。この機能は優れものです。プログラムや他のオブジェクトを別のライブラリーに置いたまま、コマンドを QGPL などのライブラリーに移動できるためです。多数のソフトウェア・ベンダーがこれを使用しています。IBM もです。例えば、BRMS コマンドにはプロダクト・ライブラリーとして QBRM があります。
コマンドのコピーを、例えばシステム・ライブラリー・リストや QGPL に配置する場合、プロキシー・コマンドも使用できます。プロキシー・コマンドは別のコマンドへのポインターです。BRMS のような IBM コマンドの場合、IBM はプロキシー・コマンド BRMS をライブラリー QSYS に配置する一方で、実コマンドは QBRM で動作しています。PRDLIB(QBRM) 値が入っているのは QBRM ライブラリーにあるコマンドです。
コマンドを作成する
次回アプリケーションやユーティリティーを作成するときは、コマンドの作成を検討していただけることと思います。コマンドはパラメーターを上手に処理して渡すことができるだけでなく、コマンド・ラインや CL プログラムで簡単に使用できます。SEU 内に新しいコマンドのプロンプトを出すことさえできます。自分のコマンドを作成し始めたら、それがなかった頃はどうやっていたのだろうと不思議に思うことでしょう。