07.REXX 外部コマンド
By 高尾 - Posted: 2008/11/19 Last updated: 2010/06/17
- Leave a Comment
REXXから外部コマンドを発行する方法について、書きます。
もっとも乱暴な話をすると、REXXプログラムの中に外部コマンドを書くと実行されます。たとえば、
TSOのSTATUSコマンドが実行されると思います。ただし、暗黙の前提をフルに使っています。
暗黙の設定を順に説明します。STATUSは変数として値をもっていないので、’STATUS’という値をもちます。これはREXXコマンドにはないので、REXXは外部環境に渡します。外部環境がTSOであった場合、無事にSTATUSコマンドが実行されます。RCは外部コマンド実行後にリターン・コードが入る特別な変数名です。
変数の暗黙の値を利用するのは、わかりにくくなる原因なので、”STATUS”というように”で囲むことが強く推奨されています。
ここで外部環境とあっさり書きましたが、状況は簡単でないことも多いでしょう。次のように環境が重なっている場合が普通かと思います。
この層になっている環境において、どれに対してコマンドを渡すか明示しておいたほうが安心です。
そのためには、ADDRESSコマンドを使います。(とはいいながらも、ADDRESS以降にどの環境をどういう名前で指定するかは決まっているので、事前にマニュアルで調べることが必要です。)
たとえば、ISPFが動作している環境でISPFに対してコマンドを出す場合、
ADDRESS ISPEXEC ‘SELECT service’
MVSが提供しているサービスを利用する場合にも、ADDRESSを使います。
ADDRESS MVS command …..
というように指定します。
ここで、commandはこのプログラム内だけで使うスタックを定義する、NEWSTACK,QSTACK,DELSTACK,DROPSTACK, MAKEBUF,DRIPBUF,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には、要素数が入っています。
以上で基本的な外部コマンドの使い方を終わります。
もっとも乱暴な話をすると、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,DROPSTACK, MAKEBUF,DRIPBUF,QBUF,QELEM)。 実行モードを制御するEXECUTIL, I/OサービスをしてくれるEXECIOなどがあります。
ここではとくに、I/OサービスのEXECIOをサンプルとしてみてみましょう。今までの勉強の確認にもなります。
/* REXX */
"ADDRESS TSO ALLOC DD(INDD) DA('SYS1.PARMLIB(IEASYS00)') SHR REUSE"
"ADDRESS MVS EXECIO * DISKR INDD (FINIS"
"ADDRESS TSO FREE DD(INDD)"
DO QUEUED()
PARSE PULL record
SAY record
END
EXIT
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は面倒なので省略します。多くの場合、うまく外部コマンドは見つかり実行されます。
/* REXX */
"ALLOC DD(INDD) DA('SYS1.PARMLIB(EIASYS00)') SHR REUSE"
"EXECIO * DISKR INDD (STEM rec. FINIS"
"FREE DD(INDD)"
DO i=1 TO rec.0
SAY rec.i
END
EXIT
EXECIOにおいて、STEM rec. が加わってます。これで配列rec.にファイルが読み込まれます。
配列からデータを取り出すために、iというカウンターでループしてデータを取り出します。配列のrec.0には、要素数が入っています。
以上で基本的な外部コマンドの使い方を終わります。
Posted in REXX入門 • • Top Of Page