07.外部コマンド

【2008/11/19 original author TAKAO】

REXXから外部コマンドを発行する方法について書きます。
もっとも乱暴な話をすると、REXXプログラムの中に外部コマンドを書くと実行されます。たとえば、

  • /* REXX */
  • STATUS
  • say RC

TSOのSTATUSコマンドが実行されると思います。ただし、暗黙の前提をフルに使っています。暗黙の設定を順に説明します。STATUSは変数として値をもっていないので、’STATUS’という値をもちます。これはREXXコマンドにはないので、REXXは外部環境に渡します。外部環境がTSOであった場合、無事にSTATUSコマンドが実行されます。RCは外部コマンド実行後にリターン・コードが入る特別な変数名です。
変数の暗黙の値を利用するのは、わかりにくくなる原因なので、”STATUS”というように ” で囲むことが強く推奨されています。

ここで外部環境とあっさり書きましたが、状況は簡単でないことも多いでしょう。次のように環境が重なっている場合が普通かと思います。

REXX
ISPF
TSO

この層になっている環境において、どれに対してコマンドを渡すか明示しておいたほうが安心です。そのためには、ADDRESSコマンドを使います(とはいいながらも、ADDRESS以降にどの環境をどういう名前で指定するかは決まっているので、事前にマニュアルで調べることが必要です)。たとえば、ISPFが動作している環境でISPFに対してコマンドを出す場合、

  • ADDRESS ISPEXEC 'SELECT service'

MVSが提供しているサービスを利用する場合にも、ADDRESSを使います。

  • ADDRESS MVS command ...

というように指定します。
ここで、commandは、このプログラム内だけで使うスタックを定義するNEWSTACK(QSTACK、DELSTACK、DROPBUF、MAKEBUF、QBUF、QELEM)、実行モードを制御するEXECUTIL、I/OサービスをしてくれるEXECIOなどがあります。

ここではとくに、I/OサービスのEXECIOをサンプルとしてみてみましょう。今までの勉強の確認にもなります。

2行目は、TSO CLISTでおなじみのAllocateコマンドです。
3行目は、MVSサービスでREXXに提供されているEXECIOです。*はレコードを全部読むという意味で、次のDISKRは読み取りを意味します。INDDはAllocateコマンドで設定したDD名です。FINISは読み終わったらファイルをクローズするという意味です。読み取られたレコードはすべてスタックにおかれています。つまり、スタックにファイルを読み取りたかったら、このままの形式で(もちろんDD名だけは考慮が必要ですが)読み取れます。
4行目は、TSO CLISTでおなじみのFREEコマンドです。アロケートしたファイルを開放します。

次のDO~ENDはスタックにある限りループします。QUEUED()はスタックの大きさを返します。スタックからデータを取りだすために、PULLし、データをrecorという変数にPARSEで割り当てます。SAYで表示することの繰り返しです。単純ながらプログラムらしくなってきましたね。

次にEXECIOの別の使い方を紹介してみます。ここでは、ADDRESSは面倒なので省略します。多くの場合、うまく外部コマンドは見つかり実行されます。

EXECIOにおいて、STEM rec. が加わってます。これで配列rec.にファイルが読み込まれます。配列からデータを取り出すために、iというカウンターでループしてデータを取り出します。配列のrec.0には、要素数が入っています。

以上で基本的な外部コマンドの使い方を終わります。

【2008/11/19 original author TAKAO】