本稿では、Kompira Enterprise のセッション機能を用いて、対話的に Linux コマンドを実行する方法をご紹介します。
※ 本稿は Kompira Enterprise 1.6系に準拠したジョブフロー結果を記載しています。
環境情報
本稿は、以下の環境で検証しています。
ソフトウェア | バージョン |
---|---|
Kompira Enterprise | 1.5.5.post7 |
OS | CentOS 7.8.2003 |
または
ソフトウェア | バージョン |
---|---|
Kompira Enterprise | 1.6.2.post4 |
OS | CentOS 8.2.2004 |
はじめに
Kompira Enterprise のジョブフローを用いてコマンドを実行する際には、[“コマンド”] というように [ ] で囲みます。この場合、各 [ ] 内のコマンドは別のセッションとして実行されます。
例えば次のようなジョブフローを見てみましょう。
["date"] -> ["export LANG=C; date"] -> ["date"]
この実行結果は次のようになります。
2021年 5月 31日 月曜日 10:41:56 JST Mon May 31 10:41:56 JST 2021 2021年 5月 31日 月曜日 10:41:56 JST
※ Kompira Enterprise 1.6系では、print しなくとも実行したコマンドの結果が出力されます。
date コマンドの出力がロケールを明示的に C ロケールに変更した2行目だけ英語になっているのがお分かりになると思います。またジョブフローにおける2行目で設定したロケールが3行目の date コマンドを実行する際に引き継がれておらず、実行結果の3行目を見ると改めて日本語出力になっています。これはつまり各行がそれぞれ別のセッションとして実行されていることを示しています。
逆に同一セッションで行わなければならない局面では、session ブロックを利用して記述します。
session ブロック
session ブロックは以下のような形式で記述します。
{ session セッションチャネル名 | ジョブフロー }
セッションの途中の状態では接続先のリモートサーバーとのやり取りをセッションチャネルを通じて行います。session ブロック終了時、$RESULT にはセッションチャネルが格納され、その data 属性に未読み込みのデータが格納された状態になります。またセッションが成功した場合には、session ブロック終了後に $STATUS に0が格納されます。
例えば、以下のような例を考えてみます。
[__node__ = ./server1] -> { session s | [s.send: "date\n"] -> <s> -> print($RESULT) -> [s.send: "export LANG=C; date\n"] -> <s> -> print($RESULT) -> [s.send: "date\n"] -> <s> -> print($RESULT) } => { if $STATUS == 0 | then: [response = $RESULT.data] -> print(response) -> print("セッションが正常に終了しました") else: print("セッション中に異常が発生しました") }
この場合の実行結果は、次のようになります。
2021年 6月 1日 火曜日 10:33:33 JST [xxx.xxx.x.x] session: 2021年 6月 1日 火曜日 10:33:33 JST Tue Jun 1 10:33:33 JST 2021 [xxx.xxx.x.x] session: Tue Jun 1 10:33:33 JST 2021 Tue Jun 1 10:33:33 JST 2021 [xxx.xxx.x.x] session: Tue Jun 1 10:33:33 JST 2021 セッションが正常に終了しました
[“コマンド”] の場合とは異なり、ジョブフロー中の2回目の date コマンドの直前に設定された LANG が3回目の date コマンドの実行時にも有効になっているのがわかると思います。
接続先サーバーとの対話
コマンドを実行した結果に応じてコマンドを投入したい場合は、セッションチャネルにおいてガード式を利用することで指定した応答を待つようにします。具体的には、上記の例でセッションの値を拾う際に <s> としたところを、<s ?? g”*]# “> のように書きます。この場合、メッセージキューの先頭から順にオブジェクトがマッチするかどうかを調べ、マッチした場合にそれまでのオブジェクトを破棄して、マッチしたオブジェクトを受信します。
ここでは
[user@server log]#
のようなシェルログインした場合のプロンプトが返ってくるのを待ちます。
g"*]# "
の部分は、glob のパターンリテラルを使用しており、”*]# ” で上記のようなプロンプトにマッチさせるようにしています。
ジョブフローにすると、例えば以下のようになります。
[ __node__ = ./server1, __use_pty__ = true ] -> { session s | [s.send: "export LANG=ja_JP.UTF-8; date\n"] -> <s ?? g"*]# "> -> print($RESULT) -> [s.send: "export LANG=C; date\n"] -> <s ?? g"*]# "> -> print($RESULT) -> [s.send: "export LANG=ja_JP.UTF-8; date\n"] -> <s ?? g"*]# "> -> print($RESULT) } => { if $STATUS == 0 | then: [response = $RESULT.data] -> print(response) -> print("セッションが正常に終了しました。") else: print("セッション中に異常が発生しました。") }
実行結果は次のようになります。
[xxx.xxx.x.x] session: export LANG=ja_JP.UTF-8; date [xxx.xxx.x.x] session: [user@server ~]# export LANG=ja_JP.UTF-8; date [user@server ~]# [xxx.xxx.x.x] session: 2021年 6月 1日 火曜日 10:46:33 JST [xxx.xxx.x.x] session: [user@server ~]# export LANG=C; date [user@server ~]# [xxx.xxx.x.x] session: Tue Jun 1 10:46:33 JST 2021 [xxx.xxx.x.x] session: [user@server ~]# export LANG=ja_JP.UTF-8; date [user@server ~]# [xxx.xxx.x.x] session: 2021年 6月 1日 火曜日 10:46:33 JST セッションが正常に終了しました。