シェルスクリプトマガジン

test

ユニケージ通信(最終回)

投稿日:2025.09.4 | カテゴリー: 記事

一般のデータベースとの違い

 業務システム開発手法の「ユニケージ」では、データベース管理システムやフレームワークなどを使わずにシステムを構築します。システムの中身が見えやすい分、仕組みやルールを理解していないと正しい開発ができません。最終回は、一般のデータベース管理システムと、ユニケージのデータベースとの違いを紹介します。


 一般的なデータベース管理システムと、ユニケージのファイルによるデータベースには「汎用型」と「業務特化型」という大きな違いがあります。
 一般的なデータベース管理システムは、24時間365日どのようなアクセスがあってもデータの保管と管理ができなくてはいけません(図1)。そのため、汎用型と呼べるでしょう。

 一方、ユニケージのデータベースは、業務というルールを基にしてデータの保管と管理が可能であればよいといえます。例えば、伝票処理なら平日8時~17時までの登録と参照ができればよいでしょう(図2上)。他のシステムからのデータ集計なら業務終了後の20時過ぎからデータの集計・保管を開始すればよいわけです(図2下)。このようにルールに即したデータの保管と管理なら、必要がない機能を省いて最適化が比較的容易です。

 ユニケージのデータベースは業務特化型です。特に、ユニケージのデータベースには業務システムで得た長年のノウハウがいろいろと盛り込まれています。

五つのレベルで管理

 ユニケージのデータベースでは、一般的なデータベース管理システムのようにマスターのテーブルだけにデータを蓄積しているわけではありません。L1~L5という五つのレベルでデータを管理しています(図3)。

 L1は入力データ、L2は業務処理で必要な中間データ、L3はマスターとなるデータ、L4は業務で参照が必要となるデータ、L5は帳票やレポートなどの出力データです。L1~L5には重複したデータが保存されています。一見無駄のように見えますが、業務システムにおいて大きなメリットになります。

L1のデータ

 L1では、基本的に一つの入力を一つのファイルで管理しています。
 例えば、一つのファイルが1枚の伝票と考えてください。システム内に入力した伝票の状態を残しておけば、もし入力を間違えてしまってもその伝票を差し替えるだけで入力が正しい状態になります。
 また、ユニケージでは、業務処理ごとに一つのプログラム(シェルスクリプト)を用意します。間違えた伝票がどの業務処理に関係するのかが分かっていれば、対応する一つのプログラムを実行するだけでシステム全体が正しい状態になります。
 日々の業務において伝票入力を間違えたり、他のシステムから異常なデータが流れてきたりすることが意外とよくあります。入力した伝票を読み出して修正して再度登録するだけならよいですが、すでに処理済みの場合は、そのデータから作られたデータがどのテーブルのどのレコード(行)のどのカラム(列)にあるかを調べて修正しなくてはいけないなど、面倒な処理が必要になることも考えられます。先に述べたようにユニケージなら該当する入力データのファイルを差し替えてプログラムを実行するだけで済みます(図4)。

L2のデータ

 L2は前述した、業務処理で必要な中間的なデータです。このようなデータを用意しておくことで、膨大なマスターデータから必要なデータを抽出しなくてよくなります。素早く業務処理を実行するには欠かせない機能です。
 なお、ユニケージのルールでは、このような中間データが不要な場合はL2を作らなくても構いません。

L3のデータ

 L3は、データベース管理システムのマスターテーブルと同じです。しかし、L3は常に最新の状態に保つ必要はありません。L1のデータに最新のL3を形作るデータが保存されているからです。
 L3は、業務が終わった深夜などに最新の状態に作り直して構いません。業務中に最新の状態にしなければ、L3生成のためのシステム負荷を増やすことなく、システムのリソースを業務処理に集中させられます。
 なお、もし業務中に大量の入力があり、それらを加工してL3のデータとして保管する場合、夜間だけでは保管作業が終わらない可能性もあります。ユニケージでは、そのようなことがないように、ユニケージ専用のコマンド群「usp Tukubai」を用意しています。usp Tukubaiでは、インメモリーでCPU固有機能を活用しながら、高速に並べ替えや抽出ができるコマンドを多数提供しています。

L4のデータ

 L4は、前述したように業務で参照が必要となるデータです。ただし、伝票処理なら業務終了後に作成した前日のデータになります。そのため、今日入力されたL1のデータと組み合わせることがあります。
 人や他のシステムがデータを参照する場合、出力が遅いのはシステムとして致命的です。よって、膨大なマスターデータから抽出せずにL4というデータを用意しておくことは、システムの利便性の面で重要です。

L5のデータ

 業務システムで帳票やレポートの出力は大切な機能です。ユニケージでは、その出力をデータベースの中に組み込んでいます。2024年1月から義務化される電帳法などにも対応しやすくなります。

ファイル管理での工夫と優位性

 L1~L5のデータすべてがファイルです。各レベルごとに多くのファイルが存在します。ちなみに、複数のファイル内からデータを抽出するのは遅いと感じるエンジニアは多いでしょう。確かにファイルのオープンとクローズは重たい処理です。前述したusp Tukubaiのコマンドを駆使して高速に検索・抽出
を実施しても満足する性能を発揮できないかもしれません。また、膨大なデータとなれば、大きなシステム負荷も発生します。
 ユニケージではファイルの中身だけでなく、ファイル名やディレクトリ名などもデータとして利用しています(図5)。

 ファイルシステムによるファイルやディレクトリの検索には、Bツリーなどの高速検索アルゴリズムが採用されています。それを活用すれば、ファイルをオープンすることなく高速・低負荷で検索ができ、絞り込んだ後で少なくなったファイルの中身から所望するデータを抽出すればよいわけです。
 また、ファイルにはデータベースのテーブルにはないメリットがあります。それは、テキストエディタで開いて中身が読める点です。ユニケージのデータは半角スペースで区切られた表形式で保存されています。
 もし、システムから出力されたデータなどにおかしな点を見つけた場合、業務を担当している社員が入力データのファイルを直接確認して問題点を見つけて解決できる可能性があります(図6)。これは、とても早い問題解決につながります。

リレーショナルと大福帳型の両立

 もう少しデータベースの仕組みに踏み込んでみます。業務システムのバックエンドで利用されているデータベース管理システムは、一般的に「リレーショナルデータベース管理システム」です。これは、さまざまな属性情報に分けてデータを保存している複数のテーブルを、従業員番号や商品コードなどのキーとなるデータで連携した構造になります。単一のテーブルにすべての情報を登録することなく管理できるので、項目数が多いデータを扱う場合に便利です。ユニケージのデータベースもキーによるデータ連携を実施しています。
 このリレーショナルデータベース管理システムでは、データの重複がないようにするための「正規化」、データの永続性を保証する「CRUD」(クラッド)は重要な機能です。ユニケージのデータベースでは、生のデータを保存・管理する点から正規化もCRUDも実施していません。前述したようにL1~L5では重複するデータを保存しています。
 CRUDは「Create」(生成)、「Read」(抽出)、「Update」(更新)、「Delete」(削除)の頭文字を取った言葉ですが、ユニケージのデータベースにはUpdateとDeleteが存在しません。では、なぜデータの永続性が保証できるのかといえば、入力日時などでどれが更新・削除されたデータなのかの判別や抽出を可能にしているからです。
 ただし、データ量が増えてくると判別や抽出に時間がかかります。そのため、前述のTukubaiコマンド、ファイル名やディレクトリ名、L4のデータなどで高速に処理できるようにしています。
 このようにユニケージのデータベースにはリレーショナルデータベース管理システムとしての側面もありますが、BI(Business Intelligence)に使われる大福帳型データベース的な側面があります。近年、業務にかかわるさまざまなデータを分析し、経営戦略に利用している企業が数多く存在します。BIは、その業務分析に使われている言葉です。分析に使われるデータは、日々の業務で発生する情報、つまり業務システムの生データです。
 リレーショナルデータベース管理システムのように正規化したデータは分析に活用できません。ユニケージのデータベースでは、日々の業務に必要なデータを提供するとともに生データを蓄積しています。
 もし、新しい業務システムを構築するときにBIまで手が回らない、また予算が捻出できないとします。リレーショナルデータベース管理システムを採用した業務システムでは、新たにBIツールを導入してからデータを蓄積、データがある程度たまった時点で分析を開始しなくてはいけません。少なくとも1年間のデータを蓄積してからでないと正しい分析ができないでしょう。

 一方、ユニケージなら業務システム構築時に生データを蓄積できる仕組みが用意されています(図7)。新たにBIツールを導入した時点から分析を開始できます。


 東京国際フォーラムで2023年9月27日~28日に開催されたイベント「日経クロステックNEXT 東京2023」の特別座談会「検証!失敗の本質~一流企業でなぜITトラブルや品質不正が相次ぐのか」で登壇した日経クロステック編集長の榊原 康氏は、最近頻発しているシステムトラブルに対して「レジリエンス」(回復力)が重要と述べていました。
 日々の業務において、人為的トラブルはつきものです。誰でも入力データを理解でき、問題がある箇所を見つけて正しいデータの入力ファイルに差し替えて、プログラムの再実行で修復できるユニケージのデータベースは、レジリエンスが重要な業務システムに合ったものといえるかもしれません。実際に、誤った入力や入力し忘れ、他のシステムからの異常データの受け取りが発生しても入力データの欠落や誤植を修正し、明け方に発生したトラブルも業務開始までには原因究明から完全復旧までを終えている事例が多数存在します。 
 また、BI的な要素も最近話題のDX(デジタルトランスフォーメーション)では重要です。BIにより業務を可視化することは、すべての企業において必要不可欠になってきています。ユニケージならその点も考慮しながら、通常の業務システムとして開発できます。

著者:ぱぺぽ

※本記事は、シェルスクリプトマガジン Vol.87(2023年12月号)に掲載した記事からの転載です。

ユニケージ通信(第5回)

投稿日:2025.08.14 | カテゴリー: 記事

排他制御

 業務システム開発手法の「ユニケージ」では、データベース管理システムやフレームワークなどを使わずにシステムを構築します。システムの中身が見えやすい分、仕組みやルールを理解していないと正しい開発ができません。第5回は、排他制御について紹介します。


 コンピュータ上で稼働している複数のプロセスから利用可能なファイルやデータベースなどの共通の資源がある場合、データの整合性を維持するために一つの資源に対して複数のプロセスが同時にアクセスしても問題が生じないように制御する必要があります。
 この制御が行われず資源に対して各プロセスが自由にアクセスできる状態の場合、データの整合性が保たれなかったり、資源そのものが消失したりする可能性があります。
 このような事態を防ぐために、あるプロセスが資源に対して書き込み中の場合、別のプロセスからの書き込みや読み込みを禁止します。書き込みが終わったら、別のプロセスの書き込
みや読み込みを許可します。この仕組みを「排他制御」と呼びます。

排他制御の種類

 排他制御の方式には「ロック」「ミューテックス」「セマフォ」などがあります。
 ロックは、共有資源にロックをかけて複数のプロセスからアクセスさせない方式です。このロックには「専有ロック」と「共有ロック」といった概念があります。専有ロックは、自分のプロセ
ス以外からの読み込みも書き込みもできない方式です。共有ロックは、自他共に読み込みができますが、他のプロセスからの書き込みを禁止する方式です。
 そのほか、「悲観ロック」と「楽観ロック」もあります。悲観ロックは、同じデータを他のプロセスが頻繁に更新するであろうという悲観的な考え方に基づく排他制御方式です。楽観ロックは、頻繁に同時アクセスが起きないだろうという楽観的な考え方に基づく排他制御方式です。システムを構築する場合、悲観ロックなのか、楽観ロックなのかを把握しておかなければいけません。
 ミューテックスは、「使用中」と「未使用」の2種類を用いてアクセス状態を判断する排他制御方式です。
 セマフォは、セマフォ変数やセマフォファイルに、同時アクセスできる数や状態に格納して管理し、その数や状態に基づいて共有資源に対する排他制御を実施する方式です。

ユニケージの排他制御

 ユニケージでは、三つ目のセマフォのような排他制御を用います。セマフォファイルとなるロックファイルが作成されていない状態を確認し、書き込みなどの処理が競合しないようにあるプログラムがロックファイルを作成します。ロックファイルが存在する間は、他のプログラムは読み込みや書き込みの操作を行わずに待機します(図1)。この区間を「排他区間」と呼びます。

 プログラムの処理が終了してロックファイルの消去が確認できたら、他のプログラムの読み込みや書き込みの操作が可能になります。
 ユニケージでは、このような排他制御を、システム設計者が定義したルールを基づいてシェルスクリプトのプログラム内に記述します。
 データベースのロックやコミットなどは、データを直接更新する際の排他制御に用いられます。一方、ユニケージではファイル内に保存したデータを更新しません。ファイルを新しく作成したり、追記したりすることでデータ更新を実現します。そのため、普段は排他制御を使わず、排他制御においては独特な方法を採用しています。

排他制御を実施するulockコマンド

 ユニケージの専用コマンド群「usp Tukubai」には、排他制御を実施するコマンドとして「ulock」が用意されています。このコマンドで、ロックファイルの作成と確認を実施して排他制御を実現します。
 ulockコマンドは、シェルスクリプトのプログラム内で図2のように用います。

3行目の「lock」がロックファイルで、

if ulock lock; then

によりlockファイルが存在しない場合は、lockファイルを作成して8行目の「fi」との間の処理を実行します。存在する場合は、lockファイルが消去されるまでifとの間の処理を待たせます。
 lockファイルは、処理が終了した後で7行目のように「rm」コマンドなどで消去しなくてはいけません。また、エラーなどで7行目が実行されなかった場合にデッドロック状態になるので注意してください。

ulockコマンドのオプション

 ulockコマンドには、表1のオプションが用意されています。

 「–timeout」と「–invalid」は、前述したデッドロックによって処理が停滞することを避けるためのオプションです。–invalidオプションを指定しない場合は、60秒でロックファイルを削除します。時間ではなく、「-1」を指定すると、削除せずにロックファイルの削除を永遠に待ちます。


著者:田渕 智也、高橋 未来哉

※本記事は、シェルスクリプトマガジン Vol.86(2023年10月号)に掲載した記事からの転載です。

ユニケージ通信(第4回)

投稿日:2025.07.24 | カテゴリー: 記事

JOIN句のようなテーブル結合

 業務システム開発手法の「ユニケージ」では、データベース管理システムやフレームワークなどを使わずにシステムを構築します。システムの中身が見えやすい分、仕組みやルールを理解していないと正しい開発ができません。第4回はSQLの「JOIN」句のようなテーブル結合を紹介します。


 業務システムなどでは、リレーショナルデータベース管理システム(RDBMS)内に作成したテーブル上にデータを格納しています。一般的に、同じ物や人などに関連する情報を一つの大きなテーブルで管理しているわけではなく、用途別や属性別に複数のテーブルに分けられて保存されています。
 このような場合、ある業務アプリケーションが必要とする情報が複数のテーブルにまたがっている場合もあります。それらの情報を一つにまとめることができれば、アプリケーションからの利用が簡単になります。
 このような複数のテーブルを一つにまとめる処理が「テーブル結合」です。ユニケージではデータを管理するのがテーブルではなく、テキストファイルという違いがあるにせよ、テーブル結合は重要な機能です。

内部結合と外部結合

 テーブル結合には、主に「内部結合」(INNER JOIN)と「外部結合」(OUTER JOIN)の2種類があります。テーブル結合では、結合する二つのテーブル上にある「キー」となる値を使って結合します。キーは、レコード(行)ごとに管理しているデータの識別子となるカラム(列)のデータです。識別子とするため、キーの値はユニーク(唯一無二)でなければいけません。
 内部結合では、キーの値で指定した条件に一致するレコードが双方のテーブルに存在する場合、そのレコードを結合して抽出します(図1)。SQLで内部結合を実行する場合、「SELECT」文の中で「INNER JOIN」句を指定します。なお、「INNER」の文字は省略できます。
 外部結合は、キーの値で指定した条件に一致するレコードが基準となるテーブルに存在する場合、基準となるテーブル内のレコードを基にして結合・抽出を実施します(図2)。基準としないもう一つのテーブルに、キーの値で指定した条件に一致するレコードがなければ、カラムの値を「NULL」(空)として結合します。

 基準となるテーブルが左か右かで外部結合を実行するSQLが異なります。左の場合、SELECT文で「LEFT OUTER JOIN」句を指定します。こうすれば、「FROM」句で指定したテーブルが基準になります。右の場合は「RIGHT OUTER JOIN」句を指定します。こちらはRIGHT OUTER JOINの後に指定したテーブルが基準となります。なお、どちらも「OUTER」の文字は省略できます。
 外部結合には「完全外部結合」(FULL OUTER JOIN)もあります。完全外部結合では、条件に一致しないレコードも結合・抽出されます。結合するレコードがない場合、カラムの値はNULLとして結合します。
 このほか、内部結合でも外部結合でもない交差結合(CROSS JOIN)もあります。交差結合では、キーに関係なく、双方のテーブル上に存在する各レコードの組み合わせでテーブルを結合・抽出します。

ユニケージのテーブル結合

 ユニケージの専用コマンド群「usp Tukubai」には、タグ形式で保存されたデータファイルを結合するコマンドとして「tagjoin1」「tagjoin2」「tagloopj」「tagloopx」などが用意されています。内部結合はtagjoin1、外部結合はtagjoin2、完全外部結合はtagloopj、交差結合ではtagloopxが使えます。
 なお、いずれのコマンドも次の二つ条件を満たしていないと正しく動作しません。後述するマスタファイルの第1カラムに条件となるキーを配置すること、キーとなるカラムの値が昇順に並んでいることです。昇順に並んでいない場合、usp Tukubaiの「tagmsort」コマンドを使って並べ替えておきます。
 tagjoin1、tagjoin2、tagloopj、tagloopxはいずれも、SELECT文の「WHERE」句のように出力するカラムを絞り込んで抽出する機能を備えていません。カラムを絞り込むには、本連載第3回で紹介した「tagself」「tagawk」「tagcond」のコマンドと組み合わせます。ちなみに、SELECT文のように複雑な検索や結合ができるのも便利です。しかし、usp Tukubaiのように各コマンドを単機能にした方がプログラムの可読性が高まり、バグの発生を抑えられます。

 それでは、二つのデータファイルを用意し、ユニケージによる内部結合と外部結合を実行していきます。用意した二つのテーブルは図3の「master」ファイル、図4の「tran」ファイルです。masterファイルには「CODE」(社員番号)、「NAME」(名前)、「AGE」(年齢)が、tranファイルには「DATE」(日時)、「CODE」(社員番号)、「AMOUNT」(金額)が格納されています。

 ユニケージでは「マスタファイル」と「トランザクションファイル」という言葉でデータファイルの性質を表します。マスタファイルは、結合時や抽出時に参照される名簿や台帳のようなファイルです。トランザクションファイルは、結合や抽出を行う際に基準となるファイルです。

内部結合

 どのキーで結合するのかの「key=カラム名」オプションと、マスタファイル、トランザクションファイルの順にデータファイルをtagjoin1コマンドの引数に指定し、次のように実行すると、内部結合を実行できます。

$ tagjoin1 key=CODE master tran ↵
DATE CODE NAME AGE AMOUNT
20230401 0000003 杉山 26 200
20230402 0000003 杉山 26 400
20230405 0000003 杉山 26 600
20230401 0000005 崎村 50 250
20230402 0000005 崎村 50 450
20230402 0000007 梶川 42 210
20230404 0000007 梶川 42 410
20230406 0000007 梶川 42 610

 まず、マスタファイル内に存在するキーの値からトランザクションファイルのレコードを抽出します。抽出したレコードのキーとなるカラムの後に、マスタファイルのレコードを追加して内部結合の処理が完了します。

外部結合

 どのキーで連結するのかの「key=カラム名」オプションと、マスタファイル、トランザクションファイルの順にデータファイルをtagjoin2コマンドの引数に指定し、次のように実行すると、外部結合を実行できます。なお、後に指定したトランザクションファイルが基準となるので左右を入れ換えるには引数に指定するデータファイルの順番を変えます。

$ tagjoin2 key=CODE master tran ↵
DATE CODE NAME AGE AMOUNT
20230401 0000001 _ _ 300
20230403 0000001 _ _ 500
20230404 0000001 _ _ 700
20230401 0000003 杉山 26 200
20230402 0000003 杉山 26 400
20230405 0000003 杉山 26 600
20230401 0000005 崎村 50 250
20230402 0000005 崎村 50 450
20230402 0000007 梶川 42 210
20230404 0000007 梶川 42 410
20230406 0000007 梶川 42 610

 マスタファイルに存在しない、結合すべきレコードは、カラムの値にNULLとして「_」(アンダーバー)を挿入して結合・抽出します。


 今回は、ユニケージでのテーブル結合を紹介しました。実際のユニケージによる開発では何百万レコードにも及ぶデータファイルの結合を実施して帳票などを作成しています。本連載では、SQLとの違いが分かりやすいようにタグ付きのデータファイルを使っていますが、本来のユニケージ開発ではタグなし
のデータファイルが一般的です。よって、usp Tukubaiの「join1」と「join2」といったコマンドを使ってテーブル結合を実施します。
 次回は、ユニケージにおける排他制御について説明する予定です。

著者:田渕 智也、高橋 未来哉

※本記事は、シェルスクリプトマガジン Vol.85(2023年8月号)に掲載した記事からの転載です。

ユニケージ通信(第3回)

投稿日:2025.07.3 | カテゴリー: 記事

SQLのようなデータ抽出操作

業務システム開発手法の「ユニケージ」では、データベース管理システムやフレームワークなどを使わずにシステムを構築します。システムの中身が見えやすい分、仕組みやルールを理解していないと正しい開発ができません。第3回は、専用コマンドでSQLのSELECT文のようなデータ抽出操作を実施します。


 今回は、ユニケージの専用コマンド群「usp Tukubai」を用いて、タグ形式で保存したデータファイルに対し、データベース問い合わせ言語「SQL」のようなデータ抽出の操作を実施します。タグ形式で保存したデータファイルとは、1行目に半角スペースで分けられたデータの項目(タグ名)が並んでいて、2行目以降にその項目ごとに分けられたデータを保存しているテキストファイルです。

SQLのような抽出操作ができるコマンド

 usp Tukubaiには、タグ形式のデータファイルを扱うコマンドが多数用意されています。例えば、「tagself」「tagawk」「tagsort」「tagcond」「tagjoin0」「tagjoin1」「tagjoin2」といったコマンドです。これらのコマンドでは、SQLの「SELECT」(検索)文のようなデータ抽出やデータ結合などの操作が可能です(表1)。このほかにもタグ形式のデータファイルを処理するコマンドは30種類以上あり、条件によって組み合わせて使用できます。

 usp Tukubaiに含まれるすべてのコマンドに共通していますが、ファイルに対してコマンドを適用しても、元のファイルを書き換えるわけではありません。コマンドの実行結果は、標準出力に渡され、元のファイルは残っています。このような特徴からSQLの「INSERT」(挿入)文、「DELETE」(削除)文、「UPDATE」(更新)文のような操作をするユニケージ専用コマンドはありません。しかし、シェルのリダイレクトである「>」を使って標準出力の内容をファイルとして出力することによって、INSERT文やDELETE文、UPDATE文、さらにテーブルを作成する「CREATE」文を実現しています。
 それでは、先ほどのtagself、tagawk、tagsort、tagcondのコマンドをSQL文と比較しながら紹介します。なお、tagjoin0、tagjoin1、tagjoin2といった、テーブルを結合するコマンドは次回に詳しく解説する予定です。
 紹介時に用いる元データとして「SAMPLE」ファイル(図1)を用意します。これらのファイルやテーブルには、「id」(社員番号)、「name」(名前)、「english」(英語名)、「residence」(居住地)、「age」(年齢)、「start」(入社年度)、「os_name」(使用パソコン)が書き込まれています。
 また、図2のSQLを実行し、MySQLなどのデータベース管理システムにSAMPLEファイルと同じ内容となる「SAMPLE」テーブルを作成します。

指定した項目のデータを抽出

 tagselfは、引数に指定した項目のデータを抽出するコマンドです。tagselfコマンドの基本構文は、次のようになります。抽出したい項目(タグ)の名前を半角スペースで区切って並べて、最後にデータファイル名を指定します。

tagself 項目名 項目名… データファイル名

 例えば、SAMPLEファイルから社員の名前と年齢だけを抽出するなら、

$ tagself name age SAMPLE ↵
name age
山田 24
佐藤 39
吉田 28
鈴木 27
小林 36
高橋 42

のようにtagselfコマンドを実行します。項目名付きで抽出したデータが表示されます。これは、次のSQLを実行したのと同じ結果です。

> SELECT name,age FROM SAMPLE; ↵
+--------+------+
| name | age |
+--------+------+
| 山田 | 24 |
| 佐藤 | 39 |
| 吉田 | 28 |
| 鈴木 | 27 |
| 小林 | 36 |
| 高橋 | 42 |
+--------+------+
6 rows in set (0.001 sec)

条件付きでデータを抽出

 SQLのSELECT文には、条件を指定してデータを抽出する「WHERE」句があります。例えば、SQLでSAMPLEデータベースから30歳よりも年齢の高い社員の名前、年齢を抽出するなら、

> SELECT name,age FROM SAMPLE WHERE age > 30; ↵
+--------+------+
| name | age |
+--------+------+
| 佐藤 | 39 |
| 小林 | 36 |
| 高橋 | 42 |
+--------+------+
3 rows in set (0.001 sec)

のように実行します。ユニケージで同じような処理を実行するには、次のようにtagawkコマンドで条件を指定します。

$ tagawk 'NR == 1{print %name,%age}NR > 1 && %age > 30{print %name,%age}' SAMPLE ↵
name age
佐藤 39
小林 36
高橋 42

 tagawkコマンドの基本構文は、

tagawk 'パターン{アクション}…' データファイル名

になります。パターンやアクションは、プログラミング言語「AWK」のパターンやアクションと同じような記述をします。
 パターンの「NR == 1」では1行目という条件、項目名が記されている行(1行目)を示しています。次の「NR > 1 && %age >30」は、2行目以降に対して、age項目が「30」より大きい行といった条件になります。これらの条件に一致したものに対して、それぞれのアクションに記した「print %name,%age」により「%項目名」で指定した名前と年齢のみが表示されます。なお、「%項目名」の指定は、AWKにはなく、tagawkコマンドの独自仕様です。
 tagawkコマンドでは、前述したようにAWKを知らないと、パターンやアクションの記述が難しいといえます。また、項目行も意識する必要があります。大小比較のような、複雑なパターンマッチングを必要としない条件であれば、tagcondコマンドが利用できます。
 tagcondコマンドの基本構文は、次のようになります。条件式には、表2のような比較演算子が使えます。

tagcond 条件式 データファイル名

 先ほどのSAMPLEファイルから30歳よりも年齢の高い社員の名前、年齢を抽出するなら、

$ tagcond '%age gt 30' SAMPLE | tagself name,age ↵

のように実行します。tagcondコマンドでは、1行目を項目行と判断して2行目以降に条件式を適用します。なお、tagcondコマンドには、項目を絞り込む機能がありません。よって、tagselfコマンドを併用します。
 tagcondコマンドは、複雑な条件を必要としない場合に用いると述べましたが、SQLのWHERE句の「AND」や「OR」のように「&&」や「||」を使って複数の条件を組み合わせられます。
 例えば、30代の社員の名前、年齢を抽出するなら、次のようにtagcondコマンドを実行します。

$ tagcond '%age ge 30 || %age lt 40' SAMPLE
| tagself name,age ↵

データを並べ替える

 SQLのSELECT文には、データを並べ替える「ORDER BY」句があります。例えば、SAMPLEデータベース内の社員名と出身地、社員の英語名を英語名の昇順に並べるなら、

> SELECT name,residence,english FROM SAMPLE ORDER BY english; ↵
+--------+-----------+-----------+
| name | residence | english |
+--------+-----------+-----------+
| 小林 | 東京 | kobayashi |
| 佐藤 | 東京 | sato |
| 鈴木 | 静岡 | suzuki |
| 高橋 | 名古屋 | takahashi |
| 山田 | 埼玉 | yamada |
| 吉田 | 沖縄 | yoshida |
+--------+-----------+-----------+
6 rows in set (0.001 sec)

のように実行します。ユニケージで同じ処理を実行するには、次のようにtagmsortコマンドとtagselfコマンドを使います。

$ tagmsort key=english SAMPLE | tagself name residence english ↵
name residence english
小林 東京 kobayashi
佐藤 東京 sato
鈴木 静岡 suzuki
高橋 名古屋 takahashi
山田 埼玉 yamada
吉田 沖縄 yoshida

 「key=項目名」には、並べ替える対象とする項目を記載します。データファイルの1行目は、項目行だと認識されて、2行目以降の並べ替えが実施されます。tagcondコマンドと同様に、tagmsortコマンドには、出力項目を絞り込む機能はないのでtagselfコマンドを併用します。
 tagmsortコマンドは、並べ替えのアルゴリズムとして「マージソート」を利用しています。また、ユニケージでは大量データの高速な並べ替え処理も必要とされているため、すべてのデータをメモリー上に読み込んでからソート処理を実施しています。
 tagmsortコマンドでは、文字列(文字コード)による昇順の並べ替えがデフォルトです。ただし、ORDER BY句の「ASC」(昇順)や「DESC」(降順)のような並べ替えも可能です。具体的には、文字列による降順なら項目名の後に「:r」を、数値による昇順なら「:n」を、数値による降順なら「:N」を付与します。
 例えば、入社年度の降順で社員名と出身地、入社年度を並べ替えるなら、SQLでは、

> SELECT name,residence,start FROM SAMPLE ORDER BY start DESC; ↵
+--------+-----------+-------+
| name | residence | start |
+--------+-----------+-------+
| 山田 | 埼玉 | 2021 |
| 鈴木 | 静岡 | 2018 |
| 吉田 | 沖縄 | 2016 |
| 佐藤 | 東京 | 2012 |
| 小林 | 東京 | 2011 |
| 高橋 | 名古屋 | 2009 |
+--------+-----------+-------+
6 rows in set (0.001 sec)

のように実行します。ユニケージなら次のようにtagmsortコマンドとtagselfコマンドを実行します。

$ tagmsort key=start:N SAMPLE | tagself name residence start ↵
name residence start
山田 埼玉 2021
鈴木 静岡 2018
吉田 沖縄 2016
佐藤 東京 2012
小林 東京 2011
高橋 名古屋 2009

 tagmsortコマンドでは、複数の条件での並べ替えも実施できます。「key=項目名」の後に「@」を付けて項目名を並べます。

文字列の一致によるデータ抽出

 SQLのSELECT文には、指定した文字列に一致したデータを抽出するための「LIKE」句があります。例えば、SAMPLEデータベース内の使用パソコンで「LIN」が末尾に付くLinux OSを使用している、社員名、年齢、使用パソコンを調べるには、

> SELECT name,age,os_name FROM SAMPLE WHERE os_name LIKE '%LIN'; ↵
+--------+------+------------+
| name | age | os_name |
+--------+------+------------+
| 佐藤 | 39 | UBUNTU_LIN |
+--------+------+------------+
| 高橋 | 42 | RHEL_LIN |
+--------+------+------------+
2 row in set (0.001 sec)

のように実行します。LIKE句では正規表現が使え、「%」が0文字以上の任意の文字列、「_」が任意の1文字に対応します。
 LIKE句と同様の処理を、ユニケージでは条件検索で登場したtagcondコマンドで実行できます。次のように条件式に正規表現を使って記述します。

tagcond '%項目名 ~ /正規表現/' データファイル名

 先ほどのSQLをtagcondコマンドで書き換えると、次のようになります。

$ tagcond '%{os_name} ~ /LIN$/' SAMPLE | tagself name age os_name ↵
name age os_name
佐藤 39 UBUNTU_LIN
高橋 42 RHEL_LIN

 「$」が行末を表す正規表現です。ちなみに、行頭は「^」、任意の1文字は「.」で表します。


 今回は、SQLのSELECT文をユニケージの専用コマンドで表してみました。次回は、今回紹介した以外の演算子、「IN」や「HAVING」、テーブル結合の「JOIN」などの句をユニケージ専用コマンドで表現する方法を解説します。

著者:田渕 智也、高橋 未来哉

※本記事は、シェルスクリプトマガジン Vol.83(2023年4月号)に掲載した記事からの転載です。

ユニケージ通信(第2回)

投稿日:2025.06.12 | カテゴリー: 記事

よく使うUNIX/Linuxコマンド

 業務システム開発手法の「ユニケージ」では、データベース管理システムやフレームワークなどを使わずにシステムを構築します。システムの中身が見えやすい分、仕組みやルールを理解していないと正しい開発ができません。第2回はよく使うUNIX/Linuxコマンドと、既存データの変換を紹介します。


 前回は、ユニケージのファイル管理について簡単に解説しました。今回はまず、ユニケージによるファイル処理に必要なUNIX/Linuxコマンドを紹介します。その後で、既存のデータベースのテーブルからデータを取り出してユニケージで扱うための準備をします。

UNIX/Linuxコマンドを使うわけ

 前回述べたように、ユニケージでは主なプログラムを「シェルスクリプト」として記述します。シェルスクリプトは、UNIX/Linuxコマンドの集まりです。
 UNIXおよびLinuxでは、端末からコマンドを入力してファイル内のデータを取り出したり、加工して別ファイルに保存したり、同じファイルに上書きしたりする処理をよく使います。ユニケージでは、この特徴を生かすことで、業務ロジックはJava、PHP、JavaScriptなどの言語、データベース管理システム
(DBMS)へのアクセスはSQL文などと分ける必要がなく、シェルスクリプト内のUNIX/Linuxコマンドですべての処理を実現しています(図1)。

 なお、UNIX/Linuxコマンドだけで業務ロジックを記述するのは、簡単ではありません。よって、業務処理によく使う専用のコマンド群として「usp Tukubai」を用意しています。

よく使うUNIX/Linuxコマンド

 UNIXやLinuxの端末にコマンドを入力すると、「シェル」というプログラムがコマンドを解釈してOS(カーネル)に対して実行に必要な処理を依頼します。依頼した処理がすべて完了した時点でコマンドの実行が終わります。シェルスクリプトでは、このような処理を先頭行から順に1行ずつ行っています。
 シェルには「Bash」(bash)、「C shell」(csh)、「Z shell」(zsh)などのいくつか種類があります。ユニケージでは、Linuxの標準シェルであるBashを利用しています。特に、Bashに用意されているコマンドの中で、ユニケージでは次のものをよく使います。

echo/dateコマンド

 「echo」は文字列や数値、変数値を出力するコマンドです(図2)。「date」は年月日と時刻の表示や設定をするコマンドです(図3)。

cat/cp/mv/rm/mkdirコマンド

 「cat」「cp」「mv」「rm」「mkdir」は、ファイルやディレクトリを操作するコマンドです(図4)。catは複数のファイルを連結するコマンド、cpはファイルやディレクトリをコピーするコマンド、mvはファイルやディレクトリを移動するコマンド、rmはファイルやディレクトリを削除するコマンド、mkdirはディレクトリを作成するコマンドです。
 なお、catコマンドはファイルの中身を出力するときにも利用します。

head/tailコマンド

 「head」は先頭から、「tail」は末尾から行単位でテキストファイルの内容を取り出すコマンドです(図5)。

grepコマンド

 「grep」は指定した文字列(正規表現で表した文字列)を含む(あるいは含まない)行をテキストファイル内から抽出して出力するコマンドです(図6)。

sedコマンド

 「sed」はテキストファイル内の文字列を置換したり、行単位で抽出したり、削除したりするコマンドです(図7)。

awkコマンド

 「awk」は、プログラミング言語「AWK」で記述したプログラムを実行するコマンドです(図8)。AWKはテキストファイルの加工処理に向いた言語で、古くからシェルスクリプト内で利用されています。

標準入力/標準出力/標準エラー出力

 UNIX/Linuxコマンドの出力先や入力先として「標準入力ファイル」「標準出力ファイル」「標準エラー出力ファイル」があります。これらのファイルを操作する場合に識別子となる「ファイルディスクリプタ」を利用します。このファイルディスクリプタですが、標準入力ファイルが「0」、標準出力ファイルが「1」、標準エラー出力ファイルが「2」になります。
 なお、デフォルトでは「0」がキーボード入力に、「1」と「2」が端末に結び付けられています。図2の「echo a b c」では、キーボードで入力されたコマンドを実行した結果の「a b c」が端末上に表示されています。
 コマンドで標準入力、標準出力、標準エラー出力を扱う上で次に紹介する「リダイレクト」「パイプ」をよく使います。

リダイレクト

 リダイレクトは「>」「<」「>>」の記号で表すコマンドです。別のコマンドに対してファイルの中身を入力として渡したり、コマンドの出力内容をファイルに書き出したりするときに使います(図9)。

パイプ

 パイプは「|」の記号で表すコマンドです。二つのコマンドの出力と入力を連結するときに利用します。例えば、fileファイルの先頭100行と末尾10行を切り取って出力するには、

$ head -100 file | tail -10 ↵

のように実行します。パイプで「head -100 file」を実行した結果を「tail -10」に渡しています。

テーブルからデータ取り込み

 ユニケージでシステムを構築する手始めとして、データベースのテーブル上にある既存データを取り込むことがよくあります。この作業にもコマンドを利用します。
 その準備として、データベース管理システム(DBMS)の機能やコマンドを利用してテーブルをCSV形式のファイルに変換して出力します。CSVとはComma Separated Valuesの略で、各行(レコード)のデータを列(カラム)ごとにカンマ(, )で区切ったテキストです。前回も触れましたが、ユニケージのデータファイルでは各行のデータがカンマではなく半角スペースで区切られています。ユニケージで扱うにはカンマを半角スペースに変換しないといけません。さらに、半角スペースを含むデータの「”」(ダブルクオーテーション)を取り除いたり、半角スペースを「_」(アンダーバー)に変換したりも必要です。
 WindowsなどのOSではテキストファイルの文字コードや改行コードがUNIX/Linuxと異なります。そのため、文字コードや改行コードの変換が必要な場合もあります。なお、UNIX/Linux上のデータベースのテーブルなら文字コードと改行コードの変換は不要です。また、半角のアルファベットや数字、記号のみのデータを保存したテーブルであれば、文字コードの変換が不要です。
 それでは順に作業を進めていきましょう。CSV形式で出力したファイルを「TABLE.CSV」とします。先ほどの文字コードの違いからCSV形式のファイルに出力するときのファイル名には、半角のアルファベットや数字を用いてください。例にしたテーブルは、Windows内のデータベースから取り出しました。  catコマンドでCSV形式のファイルの中身を確認してみると、図10のように日本語の文字列が含まれているので文字が化けています。Windowsの文字コード*1は、シフトJISに機種依存文字を追加した「コードページ932」(CP932)です。それに対して、UNIX/Linuxの文字コードは「UTF-8」です。この違いにより、文字化けが発生しています。

 改行コードは表示されないので、「hexdump」コマンドで16進に変換して確認します(図11)。最後に「0a0d」があります。「0d」はCR、「0a」はLFのコードで、これはWindowsの改行コードです。UNIX/Linuxの場合は「0a」のLFのみになります。

 ユニケージのデータファイル形式に変換する前に文字コードと改行コードを変換します。それには、UNIX/Linuxコマンドである「uconv」を使います。「-stou」はシフトJISからUTF-8へ変換するオプション、「-Lu」はUNIX/Linuxの改行コードに変換するオプションです*2

$ uconv -Lu -stou TABLE.CSV ↵
りんご,みかん,いちご
バナナ, メロン, スイカ

 変換した結果は、端末上に出力されます。この出力結果を「fromcsv」コマンドにパイプで渡すとユニケージのデータファイル形式に変換されます。このfromcsvは、usp Tukubaiに含まれている、ユニケージのコマンドです。

$ uconv -Lu -stou TABLE.CSV | fromcsv ↵
りんご みかん いちご
バナナ メロン スイ

 最後に、リダイレクトを使ってファイル(ここでは「TABLE」)に書き込めば、ユニケージのデータファイルが完成します。

$ uconv -Lu -stou TABLE.CSV | fromcsv > TABLE ↵

 次回は、ユニケージのデータファイルからデータを取り出してSQL文のように操作する方法を紹介します。

*1 実は、Windowsも内部はUTF-8を利用しています。しかし、日本語を使用するユーザーが扱う文字コードは、標準でCP932になっています。
*2 機種依存文字は変換できないのでシフトJISからUTF-8への変換で構いません。

著者:田渕 智也、高橋 未来哉

※本記事は、シェルスクリプトマガジン Vol.82(2023年2月号)に掲載した記事からの転載です。

ユニケージ通信(第1回)

投稿日:2025.05.22 | カテゴリー: 記事

ファイルによるデータ管理

業務システム開発手法の「ユニケージ」では、データベース管理システムやフレームワークなどを使わずにシステムを構築します。システムの中身が見えやすい分、仕組みやルールを理解していないと正しい開発ができません。第1回はユニケージの特徴の一つである、ファイルによるデータ管理を紹介します。


 業務システムの開発手法である「ユニケージ」では、システムの開発においてデータおよびその管理が最も重要と考えています。
 一般的なシステム開発では、テーブルなどは定義するものの、データの保存・操作・管理をリレーショナルデータベース管理システム(RDBMS)というソフトウエアに任せています。そして、データの操作や管理には、問い合わせ言語の「SQL」を使用しています。
 一方、ユニケージでは、データの保存にテキストファイルを利用します。入力されたデータはほぼそのままの状態で保管し、最新のデータを抽出できるような工夫が加えられています。データの操作や管理には、UNIX系OSやLinuxに備わっている標準のコマンドおよび、基本的なデータ操作のための独自コマンド(usp Tukubai)を使います。
 データベースエンジニアにとって、ユニケージにおけるデータの扱い方や操作・管理方法は特殊に見えます。しかし、ユニケージのやり方は、一般的な業務処理や業務システムに対して多くの利点があります。
 ユニケージの開発元であるユニバーサル・シェル・プログラミング研究所では、データベースエンジニアやシステムエンジニア、または企業のシステム管理者がユニケージ開発について学べるようにさまざまな教育を用意しています。まずは教育講座「速習・SQLからの移行編」を基に、SQLによるデータ操作がユニケージではどのように実現されているのかを数回に分けて解説します。第1回は、ユニケージのファイル管理です。

ユニケージとは

 ファイル管理を紹介する前に、ユニケージの特徴をまとめておきます。ユニケージは、UNIX系OSやLinuxなどのOSの基本機能を使いこなして、企業システムを構築する手法です。主なプログラムをシェルスクリプトで開発し、データの保存や管理にはテキストファイルを用います。テキストファイルで管理するといってもデータの永続性を保証する「CRUD」(Create Read Update Delete)はユニークな方法で実現しています。
 RDBMSやフレームワークを使う一般的なシステムに比べて、ユニケージで開発したシステムは次のような利点があります。

(1)データ管理の仕組みが簡単なため、参照中心のシステムなどではデータ処理の高速化が期待できる。
(2)スクリプトとして処理速度がネックになる部分には独自コマンドを用意し、データを逐次処理しているため、業務処理に対する高速化が期待できる。
(3)システムすべてをテキストベースのファイルで開発しているため、プログラムのデバッグだけでなく、データ自体のデバッグがやりやすい。また、スクリプトによりすぐに修正や確認ができる。
(4)RDBMSやフレームワークに頼らないため、型にはまらない、思い切ったシステム設計やパフォーマンス改善ができる。
(5)業務という単位で処理を単一のスクリプトにまとめているため、構造が分かりやすく動作も調べやすい。

 ただし、ユニケージでシステムを開発する場合に他の開発手法に比べて、次の点が重要です。

(1)データの配置やレイアウト、ワークフローなどでシステムの性能や設計難易度が変わるため、データを扱う深い知識が必要である。
(2)データをストリーム(流れ)で逐次処理するような設計に慣れておく必要がある。
(3)データに対する排他制御などの仕組みは、自身で用意しなくてはいけないのでシステム設計に対するさまざまな知識が必要である。
(4)不用意なバグの発生を防いだり、高度なパフォーマンス改善を実施したりするには、OSやハードウエアの知識が不可欠である。

 シェルスクリプトとテキストファイルでシステムを開発できるといった、誰でも始めやすいユニケージですが、ユニケージ流のやり方を身に付けないと失敗します。

RDBMSとユニケージのデータ管理・処理の違い

 通常、RDBMSではデータベース内のテーブルでデータを保存・管理し、標準化された問い合わせ言語のSQLを使ってアクセスして更新や検索などのデータ処理を実施します(図1)。一方、前述したようにユニケージでは、テキストファイルにデータを保存し、シェルスクリプトを使ってデータを処理します(図2)。表1に示したように、ユニケージにはSQLの各文や句に相当するコマンドがいくつか用意されています。
 なお、ユニケージでは、データベースの管理するプログラムに相当するものがありません。「ulock」コマンドなどを用意していますが、基本的にはUNIX/Linuxのファイル管理機能を利用して排他制御などのデータ管理を実現しています。
 データベースの排他制御は、RDBMSにとっても重たい処理です。ユニケージではファイルに対する排他制御を使わずにデータの更新処理を実現しています。これについては、本連載で少しずつ触れています。

データ保存のファイル形式

 ユニケージでは、次の3種類の形式でデータをテキストファイルに保存しています。

(1)フィールド形式 … フィールド(列)に分けてデータを保存する(図3)
(2)タグ形式 … 1行目にデータの項目名が並び、2行目以降にデータをフィールドごとに分けて保存する(図4)
(3)ネーム形式 … 1列目に項目名が並び、2列目以降にデータを分けて保存する(図5)

 実際のシステムでは(1)のフィールド形式でデータを保存することが多いといえます。ただし、本連載ではRDBMSとの比較が分かりやすいように、(2)のタグ形式を扱います。
 前述したように、タグ形式は1行目にデータの項目名が並びます。2行目以降が実際のデータです。項目ごとのデータは、一つの半角スペースで区切られています。項目名やレコード(行)の長さに制限はありません。
 シェルスクリプトやファイルの特性上、「int」や「date」といったデータ型は存在しません。「1.23」のような浮動小数点や、「2022/10/25」のような日付も単なる文字列として扱われます。型はないですが、ユニケージでは文字列を数字や日付として演算するための独自コマンドを用意しています。

データ更新処理

 ユニケージでは、基本的に図6のようなコマンドでテキストファイルを加工してデータの更新を実現します。入力ファイルとしてデータを保存したテキストファイルを渡し、コマンドで加工後にその結果を別のテキストファイルに出力します。この出力ファイルから更新後のデータが取得できるわけです。

 このような処理を実施する場合にいくつかの注意点があります。まず、入力ファイルのサイズが100Gバイトあれば、加工後の出力ファイルも同じサイズになる可能性があります。データを絞り込んで処理しない限り、それだけの領域を確保しなくてはいけません。また、データ加工時にはストレージからのファイルの読み込みと書き込みが発生します。そのため、ファイルI/Oがボトルネックなって期待していた性能が出ないことが考えられます。
 よって、RDBMSよりもデータを保存するテキストファイルには工夫が求められます。例えば、商品マスターであれば、キーとなる「商品コード」(CODE)と各項目(NAME、PRICE、VENDOR、ATTR1、ATTR2、ATTR3)を横に並べた1ファイルよりも、キーと項目を1対ずつセットにしたファイル群の方が一つのファイルサイズを小さくできます(図7)。ちなみに、このようにキーバリュー形式のデータファイルを、ユニケージでは「分割マスター」と呼んでいます。

 このように、ユニケージでは一つのレコードに多くの項目を持つよりも不要な項目を削り、区分別にファイルを用意するなどの工夫が必要です。ファイルの数は増えても、ファイル内の項目数を減らすことで効率に処理できるといった特徴があります。

ファイルにはマスターとトランザクションがある

 RDBMSでは、データベース内のテーブルにデータを保存しています。基本的にほとんどのテーブルはマスターとして扱われます。ユニケージでは、入力ファイルか、出力ファイルか、マスターとして保存するファイルか、一時ファイルかなどの利用目的の違いを常に意識しなくてはいけません。特に、「マスター」と「トランザクション」という名前で性質の違うファイルを分けています。
 マスターと呼ばれるファイルは、前述の分割マスターのように各レコードが行頭のキーとなるユニーク(唯一無二)なコードによって識別できます。その後に項目ごとの値(バリュー)が並びます(図8)。このマスターの特徴は次のようになります。

・キーが昇順に整列されている
・キーがユニークである
・キーがレコードの一番左側に配置する

 一方、トランザクションと呼ばれるファイルは、随時発生する情報(データ)をレコード単位にまとめたものです(図9)。例えば、次のような特徴があります。

・レコードを識別する明確なキーが存在しない
・時間の経過とともに随時レコードが増えたり減ったりする
・マスターにひも付くキーを左側に配置する
・項目ごとの値を右側に配置する
・キーはユニークとは限らない

 今後の連載でマスターやトランザクションが登場しますが、そのときまでにこれらの特徴を捉えておいてください。

 次回は、ファイルおよびデータ処理に必要となるコマンドと、実際にRDBMSからテーブルを取り出してユニケージで処理する例を紹介します。

著者:田渕 智也、高橋 未来哉

※本記事は、シェルスクリプトマガジン Vol.81(2022年12月号)に掲載した記事からの転載です。

Hinemos導入とエージェント起動

投稿日:2025.03.21 | カテゴリー: コード

 2025年4月号特集3を読むための準備として、Linuxディストリビューション「Red Hat Enterprise Linux 9」(RHEL9)環境にHinemosをインストールしてエージェントを起動する方法を紹介します。このコンテンツは、2024年10月号のシェルスクリプトマガジンVol.92特集2を基にしています。以下では、インストール先のホスト名が「rhel-manager」、IPアドレスが「172.16.63.245」の場合を例に、作業手順を解説します。他のホスト名やIPアドレスを利用している場合には、適宜読み替えてください。
 Hinemosのシステムは、「マネージャサーバ」「クライアント」「管理対象ノード」で構成されます。(図1)。


 マネージャサーバは、Himemosの運用管理機能を提供するHinemosマネージャ(以下、マネージャ)が稼働するマシンです。管理対象の情報を保持したリポジトリと、監視やジョブといった各機能で扱うデータを保管するデータベースを保持します。
 クライアントは、オペレータが利用するGUIベースの操作端末です。OSに専用ソフトウエアをインストールして使う「リッチクライアント」と、Webブラウザで操作できる「Webクライアント」の2種類があります。今回は、マネージャサーバにWebクライアントをインストールして、それをWebブラウザで使うことにします。
 管理対象ノードは、監視やジョブ実行などを行うHinemosの管理対象となるマシンです。利用する機能によっては、管理対象ノードに「Hinemosエージェント」(以下、エージェント)やSNMP*サーバーなどのソフトウエアをインストールする必要があります。今回は、マネージャサーバ自身にエージェントをインストールして、管理対象ノードにします。

【SNMP】 リモート機器を監視、制御するためのネットワークプロトコル。Simple Network Management Protocolの略。

マネージャの導入準備

 マネージャをインストールする前に、マネージャの動作に必要なパッケージをインストールします。rhel-managerに管理者(rootユーザー)でログインしてから、次のコマンドを実行してください。

# dnf install -y java-1.8.0-openjdk tar unzip vim ↵
# dnf install -y google-noto-sans-cjk-ttc-fonts java-1.8.0-openjdk-devel lsof net-snmp net-snmp-utils sysstat tcpdump wsmancli zip ↵

 なお、2回目のdnfコマンドでインストールしているパッケージは必須ではありませんが、インストールが推奨されているものです。特別な理由がなければインストールすることをお勧めします。以下では、これらの推奨パッケージもインストールしたものとします。
 続いて、次のコマンドを実行してロケール(言語設定)を日本語にします。

# dnf install -y glibc-langpack-ja ↵
# localectl set-locale LANG=ja_JP.UTF-8 ↵

 さらにSELinux*を無効にします。SELinuxが有効になっていると、マネージャをインストールできないからです。SELinuxを無効にするには、「/etc/selinux/config」ファイルの「SELINUX」行を次のように書き換えてから、RHEL9を再起動します。

SELINUX=disabled

【SELinux】 強制アクセス制御と呼ばれるセキュリティ機能を提供するセキュリティモジュール。Security-Enhanced Linuxの略。

 なお、同行が「SELINUX=enforcing」の場合には、SELinuxが有効になります。「SELINUX=permissive」の場合には、SELinuxによるアクセス制御は無効になりますが、監査ログの記録は有効になります。
 マネージャサーバがクライアントや管理対象ノードからの接続を受け付けられるように、ファイアウォールの設定もします。RHEL9では、デフォルトでファイアウォールが有効になっています。そのため、ファイアウォールを無効にするか、接続を待ち受けるポートを開放する必要があります。
 ファイアウォールを無効にするには、次のコマンドを実行します。

# systemctl stop firewalld ↵
# systemctl disable firewalld ↵

 ファイアウォールを有効にしておきたい場合には、ポートを開放する設定をします。例えば、TCPの22番ポートと80番ポートを開放するには、次のようにfirewalldコマンドを実行します。

# firewall-cmd --permanent --add-port={22/tcp,80/tcp}  ↵

 同様の手順で、表1に示すポートをすべて開放する設定をしてください*1。設定後、次のコマンドを実行することでファイアウォールに反映されます。

# firewall-cmd --reload ↵

*1 開放するポートの詳細については、「Hinemos ver.7.1 基本機能マニュアル」(https://github.com/hinemos/hinemos/releases/download/v7.1.0/ja_Base_Linux_7.1_rev1.pdf)の「2.2.9 ネットワークの要件」を参照してください。

表1 マネージャサーバで開放すべきポート

プロトコルリッチクライアントや管理対象ノードからの接続待ち受けポートWebクライアントの接続待ち受けポート
TCP22,8080,8081,8082,8083,8443,8444,8445,2400180,443
UDP161,162,514

 最後に、マネージャサーバのホスト名の名前解決ができることを確認します。名前解決ができない場合、マネージャがうまく動作しないことがあります。
 次のようにpingコマンドを実行して、自分自身から応答があることを確認してください。

# ping rhel-manager ↵

 「Name or service not known」と表示される場合には、名前解決ができていません。そのときには、次のコマンドを実行して名前解決用の情報を登録します。他のホスト名やIPアドレスを利用している場合には、適宜読み替えてください。

# echo 172.16.63.245 rhel-manager >> /etc/hosts ↵

 以上で事前準備は完了です。

マネージャの導入と起動

 マネージャやWebクライアント用コンポーネント、管理対象ノードにインストールするエージェントのパッケージは、GitHubリポジトリのリリースページ(https://github.com/hinemos/hinemos/releases)から入手できます。ここから、最新版をインストールしてください。
 今回は、2024年9月上旬時点の最新版である「Hinemos ver.7.1.0」のパッケージをインストールします。マネージャのパッケージは「hinemos-7.1-manager-7.1.0-1.el9.x86_64.rpm」、Webクライアント用コンポーネントのパッケージは「hinemos-7.1-web-7.1.0-1.el9.x86_64.rpm」です。これらを「/tmp」ディレクトリなどにダウンロードし、ダウンロードしたディレクトリで次のコマンドを実行するとインストールできます。

# rpm -ivh hinemos-7.1-manager-7.1.0-1.el9.x86_64.rpm ↵
# rpm -ivh hinemos-7.1-web-7.1.0-1.el9.x86_64.rpm ↵

 GitHubリポジトリからも直接インストールできます。それには、次のようにrpmコマンドを実行します。

# rpm -ivh https://github.com/hinemos/hinemos/releases/download/v7.1.0/hinemos-7.1-manager-7.1.0-1.el9.x86_64.rpm  ↵
# rpm -ivh https://github.com/hinemos/hinemos/releases/download/v7.1.0/hinemos-7.1-web-7.1.0-1.el9.x86_64.rpm ↵

 パッケージのインストール後、次のコマンドを実行するとマネージャとWebクライアントが起動します。

# systemctl start hinemos_manager ↵
# systemctl start hinemos_web ↵

エージェントの導入と起動

 続いて、マネージャサーバにエージェントを導入して、自分自身を管理対象ノードとして取り扱えるようにします*2。それにはまず、次のコマンドを実行して、エージェントの実行に必要なパッケージをインストールします。

# dnf install -y openssh-clients ↵

*2 マネージャサーバ以外のコンピュータにエージェントをインストールする場合の作業手順については、「Hinemos ver.7.1 基本機能マニュアル」の「2.2.5Hinemosエージェントの要件」などを参照してください。

 ファイアウォールも設定します。ファイアウォールを無効にするか、表2に示すポートを開放してください。

表2 管理対象ノードで開放すべきポート

プロトコル開放すべきポート
TCP22
UDP161,24005

 さらに、次のコマンドを実行してsnmpdサービス(SNMPサーバー)を起動します。これにより、マネージャサーバのCPUやメモリーなどのリソース情報をHinemosが取得できるようになります。

# systemctl start snmpd ↵

 ここまでの作業で、エージェントをインストールする準備が整いました。エージェントのパッケージは「hinemos-7.1-agent-7.1.0-1.el.noarch.rpm」です。これを「/tmp」ディレクトリなどにダウンロードし、ダウンロードしたディレクトリで次のコマンドを実行するとインストールできます。

# HINEMOS_MANAGER=172.16.63.245 rpm -ivh hinemos-7.1-agent-7.1.0-1.el.noarch.rpm ↵

 シェル変数HINEMOS_MANAGERには、マネージャサーバのIPアドレスを設定します。
 先ほどと同様に、GitHubリポジトリからも直接インストールできます。それには、次のようにrpmコマンドを実行します。

# HINEMOS_MANAGER=172.16.63.245 rpm -ivh https://github.com/hinemos/hinemos/releases/download/v7.1.0/hinemos-7.1-agent-7.1.0-1.el.noarch.rpm ↵

 最後に、次のコマンドを実行すればエージェントが起動します。

# systemctl start hinemos_agent ↵

-->