$ZF(-100) を使用したプログラムまたはシステム・コマンドの実行
$ZF(-100) 関数は、InterSystems IRIS® プロセスによるホスト・オペレーティング・システムの実行可能プログラムまたはコマンドの呼び出しを許可します。これは、特別なコールアウト共有ライブラリなしで使用できる唯一の $ZF 関数です (“InterSystems コールアウト・ライブラリの作成” を参照してください)。この章で説明する項目は以下のとおりです。
-
はじめに — $ZF(-100) の構文および機能の概要。
-
プログラムの実行 — プログラムはオプションで非同期に実行することもオペレーティング・システム・シェル内で実行することもできます。
-
コマンドの記録と出力のリダイレクト — オプションの設定を使用して、コマンドを記録したり、入出力をリダイレクトしたりできます。
-
%System_Callout:USE 権限の追加 — この権限は $ZF(-100) を使用するために必要です。
"ObjectScript リファレンス" の "$ZF(-100) (ObjectScript)" も参照してください。
はじめに
$ZF(-100) は、コマンド行インタフェースの機能と同様の機能を提供します。これを使用すると、ホスト・オペレーティング・システムの実行可能プログラムまたはコマンドを呼び出すことができます。この関数の構文は次のとおりです。
status = $ZF(-100, keywords, command, arguments )
最初の引数はリテラル -100 である必要があります。その他の 3 つの引数には、以下の情報を指定します。
-
keywords — さまざまなオプションを指定するキーワードが含まれる文字列。例えば、文字列 "/ASYNC/LOGCMD" は、プログラムを非同期に実行し、コマンド行をログ・ファイルに書き込む必要があることを指定します。
-
command — 呼び出すプログラムまたはシステム・コマンドを指定する文字列。実行可能プログラムのフル・パスを指定しないと、オペレーティング・システムでは標準の検索パス・ルールが適用されます。
-
arguments — コマンドの引数は一連のコンマ区切り式として指定されます (以下の例で示しています)。
$ZF(-100) 関数は、オペレーティング・システムおよび呼び出されたプログラムによって判断された終了状態コードを返します。
以下の例では、3 つの文字列が echo コマンドに渡された後、状態コードが表示されます。この例ではキーワードは使用されていないので、keywords 引数は空の文字列になっています。最後のコマンド引数は、引用符付き文字列を指定します (標準の ObjectScript 文字列ルールに従っています)。
USER>set status = $ZF(-100,"","echo","hello","world","""goodbye now""")
hello world "goodbye now"
USER>write status
0
以下のセクションでは、さらに、さまざまな $ZF(-100) オプションの例を示しています。キーワードおよびその他のオプションの概要は、"コールアウトのクイック・リファレンス" の章の “$ZF(-100) : プログラムまたはシステム・コマンドの実行” を参照してください。
プログラムの実行
$ZF(-100) を使用すると、同期的または非同期的に、オペレーティング・システム・シェルを呼び出してまたは呼び出さずに、プログラムまたはコマンドを実行できます。既定では、シェルを呼び出さずに同期的に実行されます。既定の実行は、関数呼び出しでオプションのキーワードを指定することによってオーバーライドできます。
以下のキーワードを使用して、プログラム実行を制御できます。
-
/ASYNC — プログラムを非同期で実行する必要があることを示します。これにより $ZF(-100) の呼び出しから、プログラムの完了を待たずに値が返されます。
-
/SHELL — プログラムをオペレーティング・システム・シェル内で実行する必要があることを示します。
前のセクションで触れたように、これらのオプションのいずれも使用しない場合は、keyword パラメータに空の文字列を指定できます。この例では、エラー・コード 1 が生成されるように、存在しないファイルを意図的にリストしようとしています。
USER>set status = $ZF(-100,"", "ls","*.scala")
ls: cannot access *.scala: No such file or directory
USER>write status
1
同じコマンドを非同期で実行すると、エラー・コードが返されるため、出力は表示されず、status は未定義になります。
USER>kill status
USER>set status = $ZF(-100,"/ASYNC", "ls","*.scala")
USER>write status
WRITE status
^
<UNDEFINED> *status
このような状況でエラー出力をリダイレクトする方法は、次のセクションの “入出力リダイレクトの使用法” を参照してください。
コマンドの記録と出力のリダイレクト
以下のキーワードによって、ログへの記録と入出力リダイレクトが制御されます。
-
/LOGCMD — プログラム・コマンドおよび引数がメッセージ・ログに送信されるようにします。
-
/STDIN、/STDOUT、および /STDERR — これらを使用して、呼び出されたプログラムの標準の入力、標準の出力、および標準のエラーをリダイレクトします。これらのキーワードの後ろには、ファイルの指定を付ける必要があります (以下の “入出力リダイレクトの使用法” を参照してください)。
コマンド引数のログへの記録
/LOGCMD キーワードによって、コマンド引数および終了状態コードがメッセージ・ログ (<install-dir>\mgr\messages.log) に記録されるようになります。これは主に、$ZF(-100) に渡された式が実際にどのように評価されたかを確認するためのデバッグ・ツールになることを目的としています。
ほとんどの場合、コマンドおよびその引数は 1 行に記録され、次の行に戻り値が記録されます。例えば、Windows では set status=$ZF(-100,"/LOGCMD","echo","hello","world") によって以下のログ・エントリが生成されます。
03/28/18-11:49:51:898 (26171) 0 $ZF(-100) cmd=echo "hello" "world"
03/28/18-11:49:51:905 (26171) 0 $ZF(-100) ret=0
ただし、UNIX® では、/SHELL が指定されていない場合、以下のように値は 1 行に 1 つずつ記録されます。
03/28/18-12:09:22:243 (26171) 0 $ZF(-100) argv[0]=echo
03/28/18-12:09:22:500 (26171) 0 $ZF(-100) argv[1]=hello
03/28/18-12:09:22:559 (26171) 0 $ZF(-100) argv[2]=world
03/28/18-12:09:22:963 (26171) 0 $ZF(-100) ret=0
いずれの場合でも、引数はプログラムで受け取られるとおりに記録されます。
入出力リダイレクトの使用法
以下のキーワードとファイル指定子は、入出力リダイレクトを制御します。
-
/STDIN=input-file
-
/STDOUT=output-file または /STDOUT+=output-file
-
/STDERR=error-file または /STDERR+=error-file
入出力リダイレクト・キーワードの後ろには、演算子 ( = または += ) と、ファイル名またはファイル・パスが続きます。演算子の前後にスペースを入れることができます。標準の入力は、既存のファイルを指す必要があります。標準の出力および標準のエラー・ファイルは、存在しない場合は作成され、既に存在する場合は切り捨てられます。ファイルを作成または切り捨てるには = 演算子を使用し、既存のファイルに追加を行うには += 演算子を使用します。標準のエラーと標準の出力が同一のファイルに送信されるようにするには、両方のキーワードに同じファイルを指定します。
次の例の最初の行では echo コマンドからファイル temp.txt に標準の出力がリダイレクトされ、2 つ目の行に結果のファイル・コンテンツが表示されています。
USER>set status = $ZF(-100,"/STDOUT=""temp.txt""","echo","-e","three\ntwo\none\nblastoff")
USER>set status = $ZF(-100,"","cat","temp.txt")
three
two
one
blastoff
次の例では、ファイル temp.txt を標準の入力にリダイレクトすることによって、このファイルの 2 行を別の方法で表示しています。tail コマンドが入力を受け入れ、最後の 2 行を表示します。
USER>set status=$ZF(-100,"/STDIN=""temp.txt""","tail","-n2")
one
blastoff
次の最後の例では、標準のエラーが temp.txt にリダイレクトされ、存在しないファイルの表示を試行しています。ここでは、コマンドを非同期で実行するために /ASYNC キーワードも使用されており、$ZF(-100) 呼び出しが値を返してから、エラー・メッセージを表示できるようになっています。ここでも 2 つ目の行 (前の例とまったく同じ) にファイルの最後の 2 行が表示されており、リダイレクトされたエラー・メッセージが含まれています。
USER>set status = $ZF(-100,"/ASYNC /STDERR+=""temp.txt""","cat","nosuch.file")
USER>set status=$ZF(-100,"/STDIN=""temp.txt""","tail","-n2")
blastoff
cat: nosuch.file: No such file or directory
%System_Callout:USE 特権の追加
$ZF(-100) は、%System_Callout:USE 権限を必要とします。インターシステムズのセキュリティ設定が最小よりも高い場合は、この権限が無効になっていることがあります。以下の手順では、%Developer ロールでこの権限を有効にする方法を示します。
-
管理ポータルを開いて、[システム管理] > [セキュリティ] > [ロール] に移動します。
-
[ロール] ページで、[名前] 列の [%Developer] をクリックします。
-
[ロール %Developer の定義編集] ページの [General] タブで、%System_Callout 権限を見つけて、[編集] をクリックします。
-
[リソースの許可を編集] ダイアログで、[許可 使用] チェック・ボックスにチェックが付いていない場合はチェックを付け、[OK] をクリックします。
%Developer ロールは InterSystems IRIS のインストール時に必ず作成されますが、一部のユーザはこのロールを使用できないように管理者が設定している場合があります。場合によっては、$ZF(-100) を使用可能にするが、その他の権限を付与しないロールをユーザに提供することが望ましいこともあります。以下の手順で、%System_CallOut:USE 権限のみを付与する新規ロールを作成します。
-
管理ポータルを開いて、[システム管理] > [セキュリティ] > [ロール] に移動します。
-
[ロール] ページで、[新規ロール作成] ボタンをクリックして、[ロール編集] ページを開きます。
-
以下のように名前と説明を入力します。
-
名前: UseCallout
-
説明: %System_CallOut リソースを使用する特権を付与する
[保存] をクリックすると、フォームに [追加] ボタンが表示されます。
-
-
[追加] ボタンをクリックすると、リソースのスクロール・リストが表示されます。リストから %System_CallOut を選択して [保存] をクリックします。[ロール編集] フォームの [閉じる] をクリックします。
-
[ロール] ページのロール定義のリストに新しい UseCallout ロールが表示されます。