# OpenVMS
ユーザーズ・マニュアル

前へ | 次へ | 目次 | 索引

# 17.4 ファイルとデバイスについての情報

ファイルとデバイスについての情報を得るには，次のレキシカル関数を使用します。

F$DEVICE | 指定された選択基準を満たすシステム上のすべてのデバイスのデバイス名を戻す。
F$FILE_ATTRIBUTES | ファイル属性についての情報を戻す。
F$GETDVI | 指定されたデバイスについての情報を戻す。
F$PARSE | ファイル指定を解析して，要求された 1 つまたは複数のフィールドを戻す。
F$SEARCH | ディレクトリでファイルを検索する。

## 17.4.1 デバイスの検索

システム・サービス $GETDVI を使用することによって特定のデバイスについての情報を得るには，デバイス名をサービスに提供しなければなりません。デバイス名がわからない場合には，F$DEVICE レキシカル関数を使用して検索できます。

F$DEVICE 関数を使用すると，デバイス名，デバイス・クラス，またはデバイス・タイプに基づくワイルドカード検索ができます。デバイス・タイプに基づいて検索を行うには，デバイス・クラスも指定しなければなりません。

コマンド・プロシージャのループの中で F$DEVICE 関数を使用すると，指定された選択基準に一致するデバイス名が戻されます。 F$DEVICE 関数を実行するたびに，選択基準に一致する次のデバイスが戻されます。デバイス名が戻される順序は一定でないことに注意してください。最後のデバイス名が戻されてから F$DEVICE 関数を呼び出すと，空の文字列が戻されます。

次の例のコマンド・プロシージャは，ユニット番号が 0 のユニット上のすべての RA60 のデバイス名を表示します。

    $ START:
    $     DEVICE_NAME = F$DEVICE("*0:","DISK","RA60")
    $     IF DEVICE_NAME .EQS. "" THEN EXIT
    $     SHOW SYMBOL DEVICE_NAME
    $     GOTO START

## 17.4.2 ディレクトリの中でのファイルの検索

ファイルを処理する際には，あらかじめ F$SEARCH 関数を使用してそのファイルが存在するかどうかを調べなくてはなりません。たとえば，次のコマンド・プロシージャは，F$PARSE を使用して，デバイスとディレクトリ文字列を STATS.DAT ファイルに適用しています。次に，F$SEARCH 関数を使用して， DISK3:[JONES.WORK] に STATS.DAT が存在するかどうか判別します。存在すれば，ファイルを処理し，存在しない場合には，別の入力ファイルを求めるプロンプトを出します。

    $ FILE = F$PARSE("STATS.DAT","DISK3:[JONES.WORK]",,,"SYNTAX_ONLY")
    $ IF F$SEARCH(FILE) .EQS. "" THEN GOTO GET_FILE
    $ PROCESS_FILE:
       .
       .
       .
    $ GET_FILE:
    $   INQUIRE FILE "File name"
    $   GOTO PROCESS_FILE

ファイルの存在を判別した後，F$PARSE または F$FILE_ATTRIBUTES 関数を使用すれば，ファイルについての補足情報を得ることができます。

    $ IF F$SEARCH("STATS.DAT") .EQS. "" THEN GOTO GET_FILE
    $ PROCESS_FILE:
    $     NAME = F$PARSE("STATS.DAT",, "NAME")
       .
       .
       .
    $ GET_FILE:
    $   INQUIRE FILE "File name"
    $   GOTO PROCESS_FILE

## 17.4.3 ファイルの古いバージョンの削除

プロシージャの終了後にユーザが必要としないファイルが作成された場合には，プロシージャを終了する前にこれらのファイルを削除またはパージします。最も新しいバージョンを除くすべてバージョンを削除するには， PURGE コマンドを使用します。ファイルの特定のバージョンを削除するには， DELETE コマンドと一緒にバージョン番号を指定します。ファイルのすべてのバージョンを削除するには， DELETE コマンドのバージョン・フィールドにワイルドカード文字を使用します。

コマンド・プロシージャの中で DELETE コマンドを使用するときに，エラー・メッセージが出されないようにするには，F$SEARCH 関数を使用して，削除する前にそのファイルが存在するかどうかをチェックします。たとえば，特定のモジュールが存在する場合にのみ TEMP.DAT というファイルを作成するコマンド・プロシージャを作成することができます。次のコマンド行は，TEMP.DAT が存在する場合にだけ DELETE コマンドを出します。

    $ IF F$SEARCH("TEMP.DAT") .NES. "" THEN DELETE TEMP.DAT;*

# 17.5 論理名の変換

論理名を変換するには，次のレキシカル関数を使用します。

F$LOGICAL | 論理名の同値文字列を戻す。
F$TRNLNM | 論理名の同値文字列または要求された属性を戻す。

注意 F$TRNLNM 関数は，OpenVMS オペレーティング・システムの以前のバージョンで使用されていた F$LOGICAL に代わるものです。コマンド・プロシージャが現在のシステム手法を使用して論理名を処理するようにするには，F$LOGICAL の代わりに F$TRNLNM を使用してください。

場合によっては，コマンド・プロシージャの変数としてシンボルではなく，論理名を使用するとよいことがあります。プログラムは，DCL シンボルにアクセスするより論理名にアクセスする方が簡単だからです。したがって，コマンド・プロシージャから実行するプログラムに情報を渡すには，シンボルを使用して情報を得てから，DEFINE または ASSIGN コマンドを使用して，シンボルの値を論理名に定義します。

また，F$TRNLNM 関数を使用して論理名の値を判断してから，その値をシンボルに割り当てることもできます。

次の例は，論理名 NAMES が定義されているかどうかをテストします。定義されている場合には，プロシージャは PAYROLL.EXE を実行し，定義されていない場合には，FILE シンボルの値を得て，この値を使用して論理名 NAMES を作成します。 PAYROLL.EXE は，論理名 NAMES を使用して従業員名のファイルを表しています。

    $ ! Make sure that NAMES is defined
    $ IF F$TRNLNM("NAMES") .NES. "" THEN GOTO ALL_SET
    $ INQUIRE FILE "File with employee names"
    $ DEFINE NAMES 'FILE'
    $ !
    $ ! Run PAYROLL, using the file indicated by NAMES
    $ ALL_SET:
    $ RUN PAYROLL
       .
       .
       .

このコマンド・プロシージャは，PAYROLL プログラムで使用される論理名を定義します。

    $ DEFINE NAMES DISK4:[JONES]EMPLOYEE_NAMES.DAT
    $ RUN PAYROLL
       .
       .
       .
    $ WRITE SYS$OUTPUT "Finished processing ",F$TRNLNM("NAMES")

プロシージャの終わりに，ファイルが処理されたことを示すメッセージが WRITE コマンドによって表示されます。

# 17.6 文字列の処理

文字列を処理するには，次のレキシカル関数を使用します。

F$CVTIME | 時刻文字列についての情報を戻す。
F$EDIT | 文字列を編集する。
F$ELEMENT | 各要素が区切り文字によって分けられている文字列から要素を取り出す。
F$EXTRACT | 文字列の一部を取り出す。
F$FAO | 出力文字列を書式化する。
F$LENGTH | 文字列の長さを決定する。
F$LOCATE | 文字列の中の文字または部分文字列を探して，オフセットを戻す。

## 17.6.1 文字列または文字の有無の判別

文字列を調べる理由の 1 つに，文字列の中に文字 (または部分文字列) が存在するかどうかの判別があります。このためには，F$LENGTH と F$LOCATE 関数を使用します。 F$LOCATE 関数が戻す値が F$LENGTH 関数が戻す値と等しければ，探している文字は存在しません。

次のプロシージャは，バージョン番号を含むファイル名を要求しています。バージョン番号が存在するかどうかを判別するために，ユーザが入力したファイル名の中に，バージョン番号の前に置くセミコロン (;)があるかどうかをテストします。

    $ INQUIRE FILE "Enter file (include version number)"
    $ IF F$LOCATE(";", FILE) .EQ. F$LENGTH(FILE) THEN -
         GOTO NO_VERSION
       .
       .
       .

F$LOCATE 関数は，セミコロンのオフセットを戻します。オフセットは 0 で始まるため，セミコロンが文字列の最初の文字であれば， F$LOCATE 関数は整数 0 を戻します。文字列の中にセミコロンがなければ，F$LOCATE 関数は，文字列の最後の文字のオフセットより 1 だけ大きいオフセットを戻します。この値は，番号 1 から始まる文字列の長さに相当する F$LENGTH が戻す長さと同じです。

## 17.6.2 文字列の一部の取り出し

文字列の一部を取り出すには， F$EXTRACT 関数または F$ELEMENT 関数のどちらかを使用します。定義されたオフセットから始まる部分文字列を取り出すには F$EXTRACT 関数を使用し， 2 つの区切り文字の間の文字列の一部を取り出すには，F$ELEMENT 関数を使用します。どちらの関数を使用するかを選択するためには，解析する文字列の一般形式がわかっていなければなりません。

ファイル指定または時刻文字列を解析するには， F$EXTRACT または F$ELEMENT を使用する必要はありません。代わりに，F$PARSE または F$CVTIME を使用して，ファイル指定または時刻文字列の一部を取り出します。

グループ名を取り出すのと同時に，グループ名の長さを判断することもできます。

文字列にその文字列の異なる部分を区切る区切り文字をが含まれている場合には， F$ELEMENT 関数を使用して，必要な部分を取り出すことができます。 F$ELEMENT を使用すると，文字列の中でカンマで区切られた部分を取り出すことにより，異なるアクセス・タイプを入手できます。システム・アクセスを判断するには，最初の要素を入手します。オーナ・アクセスを判断するには，2 番目の要素を入手します。以下も同様です。 F$ELEMENT 関数を使用する場合には，要素番号は 0 から始まります。この理由から，4 番目の要素を指定するときは，整数 3 を使用します。

次のコマンド・プロシージャは， F$EXTRACT 関数を使用して UIC のグループ部分を取り出します。このとき，ユーザの UIC グループに応じて，異なるコマンド・セットを実行できます。

    $ UIC = F$USER()
    $ GROUP_LEN = F$LOCATE(",",UIC) - 1
    $ GROUP = F$EXTRACT(1,GROUP_LEN, UIC)
    $ GOTO 'GROUP'_SECTION
       .
       .
       .
    $ WRITERS_SECTION:
       .
       .
       .
    $ MANAGERS_SECTION:
       .
       .
       .

最初に，F$USER 関数によって UIC を判別します。次に，F$LOCATE を使用してコンマのオフセットを検出して，グループ名の長さを判別します。コンマによって UIC のグループとユーザ部分が区切られているからです。左括弧とコンマの間にあるものがグループ名の部分になります。たとえば，UIC [WRITERS,SMITH] のグループ名は WRITERS です。

長さを判別した後，プロシージャは F$EXTRACT 関数によってグループの名前を取り出します。名前はオフセット 1 で始まり，コンマの前の文字で終わります。最後に，該当するラベルに処理を移します。

次の例では，保護コードの各アクセス・タイプがカンマでどのように区切られるかを示しています。

    $ UIC = F$USER()
    $ GROUP = F$EXTRACT(1, F$LOCATE(",",UIC) - 1, UIC)
    $ GOTO 'GROUP'_SECTION

次の例では，保護コードの各アクセス・タイプがカンマでどのように区切られるかを示しています。

    $ PROT = F$ENVIRONMENT("PROTECTION")
    $ SHOW SYMBOL PROT
    PROT = "SYSTEM=RWED, OWNER=RWED, GROUP=RE, WORLD"

この例のコマンドは，省略時の保護コードからワールド・アクセスの部分 (4 番目の要素) を取り出します。

    $ PROT = F$ENVIRONMENT("PROTECTION")
    $ WORLD_PROT = F$ELEMENT(3,",",PROT)
       .
       .
       .

この例では，F$ELEMENT 関数は， 3 番目のコンマと文字列の終わりの間にあるすべてを戻すため，省略時の保護がワールド・ユーザの読み込みアクセスを許容している場合には，文字列 " WORLD=R" が戻されます。

ワールド・アクセス文字列を得たら，さらにそれを調べる必要があります。たとえば，次のようにします。

    $ PROT = F$ENVIRONMENT("PROTECTION")
    $ WORLD_PROT = F$ELEMENT(3,",",PROT)
    $ IF F$LOCATE("=", WORLD_PROT) .EQ. F$LENGTH(WORLD_PROT) -
      THEN GOTO NO_WORLD_ACCESS
       .
       .
       .

## 17.6.3 出力文字列の書式化

WRITE コマンドを使用すると，文字列をレコードに書き込むことができます。レコード内のカラムをそろえるには， F$FAO 関数を使用してレコード・フィールドを定義し，これらのフィールドにプロセス名とユーザ名を格納します。 F$FAO 関数を使用する場合には，制御文字列を使用してレコード内のフィールドを定義します。その後，これらのフィールドに格納する値を指定します。

レコード内のフィールドを書式化する別の方法として，文字列オーバレイを使用する方法があります。しかし，F$FAO 関数の方が文字列オーバレイより強力です。 F$FAO 関数を使用すると，広範囲にわたる出力操作を実行できます。

この例に示したコマンド・プロシージャでは，WRITE コマンドを使用して，システムのプロセスのプロセス名と PID 番号を表示します。

    $ ! Initialize context symbol to get PID numbers
    $ CONTEXT = ""
    $ ! Write headings
    $ WRITE SYS$OUTPUT "Process Name     PID"
    $ !
    $ GET_PID:
    $ PID = F$PID(CONTEXT)
    $ IF PID .EQS. "" THEN EXIT
    $ WRITE SYS$OUTPUT F$GETJPI(PID,"PRCNAM"),"     ", F$GETJPI(PID,"PID")
    $ GOTO GET_PID

次に示すように，WRITE コマンドからの出力では，プロセス名とユーザ名の間に 5 つのスペースが挿入されますが，桁そろえは行われません。

    Process Name     PID
    MARCHESAND     2CA0049C
    TRACTMEN     2CA0043A
    FALLON     2CA0043C
    ODONNELL     2CA00453
    PERRIN     2CA004DE
    CHAMPIONS     2CA004E3

この例の中では，コマンド・プロシージャは，F$FAO 関数を使用して， 16 文字フィールドと 12 文字フィールドを定義しています。 F$FAO 関数は，最初のフィールドにプロセス名を収めてから，スペースはスキップして，2 番目のフィールドに PID を収めます。

    $ ! Initialize context symbol to get PID numbers
    $ CONTEXT = ""
    $ ! Write headings
    $ WRITE SYS$OUTPUT "Process Name     PID"
    $ !
    $ GET_PID:
    $ PID = F$PID(CONTEXT)
    $ IF PID .EQS. "" THEN EXIT
    $ LINE = F$FAO("!16AS !12AS", F$GETJPI(PID,"PRCNAM"), F$GETJPI(PID,"PID"))
    $ WRITE SYS$OUTPUT LINE
    $ GOTO GET_PID

ここで，プロシージャを実行すると，桁がそろえられます。

    Process Name     PID
    MARCHESAND       2CA0049C
    TRACTMEN         2CA0043A
    FALLON           2CA0043C
    ODONNELL         2CA00453
    PERRIN           2CA004DE
    CHAMPIONS        2CA004E3

次の例は，オーバレイを使用して， RECORD シンボルの最初の 16 文字 (オフセット 0 から始まる) にプロセス名を収め，次の 12 文字 (オフセット 17 から始まる) に PID を収めます。

    $ ! Initialize context symbol to get PID numbers
    $ CONTEXT = ""
    $ ! Write headings
    $ WRITE SYS$OUTPUT "Process Name     PID"
    $ !
    $ GET_PID:
    $ PID = F$PID(CONTEXT)
    $ IF PID .EQS. "" THEN EXIT
    $ RECORD[0,16]:= 'F$GETJPI(PID,"PRCNAM")'
    $ RECORD[17,12]:= 'F$GETJPI(PID,"PID")'
    $ WRITE SYS$OUTPUT RECORD
    $ GOTO GET_PID

このプロシージャでは，F$FAO 関数で作成したのと同じ書式が生成されます。

    Process Name     PID
    MARCHESAND       2CA0049C
    TRACTMEN         2CA0043A
    FALLON           2CA0043C
    ODONNELL         2CA00453
    PERRIN           2CA004DE
    CHAMPIONS        2CA004E3

# 17.7 データ・タイプの処理

データを文字列から整数に，整数から文字列に変換するには，次のレキシカル関数を使用します。

F$CVSI | 文字列からビット・フィールドを取り出して，符号付きの値である結果を整数に変換する。
F$CVUI | 文字列からビット・フィールドを取り出して，符号なしの値である結果を整数に変換する。
F$INTEGER | 文字列式を整数に変換する。
F$STRING | 整数式を文字列に変換する。
F$TYPE | シンボルのデータ・タイプを判別する。

前へ | 次へ | 目次 | 索引