【Shellscript】出力結果から特定の列を取得して特定の文字であることを確認する

今回、LifeKeeper起動の自動化スクリプトの作成にあたり、ステータス確認時のShellScriptの書き方について悩ませたので、記録しておきたいと思います。

やりたいこと

以下稼働系のサーバと待機系のサーバ、いずれの場合でも適用可能なスクリプトを作成する。

【稼働系のサーバ】
①LifeKeeperのステータス確認コマンド実行。
②STATEが"ISP"であること、ハートビートのSTATEが"ALIVE"であることを確認する
③STATEが"ISP"でない場合(OSUが存在する場合)、最上位のリソース(TAG)を再起動する。
 →この「最上位のリソース(TAG)を再起動する」の部分が難しかったです。

【待機系のサーバ】
①LifeKeeperのステータス確認コマンド実行。
②STATEが"OSU"であること、ハートビートのSTATEが"ALIVE"であることを確認する

稼働系のサーバのLifeKeeperのステータス確認コマンド実行結果

以下は稼働系のサーバのLifeKeeperのステータス確認コマンド実行結果の一例です。
本来であればSTATEがすべて"ISP"で、ハートビートのSTATEが"ALIVE"である状態が正しいですが、このような感じでOSUが混在していることがあるので、その際は上位リソースの再起動が必要となります。
※最上位のリソース(TAG)は以下でいう「Japan」「Global」「Asia」。

BACKUP   TAG              ID                                   STATE  PRIO  PRIMARY
node2    Japan            IP-10.1.5.xx                         ISP       1  node1
node2     /test           /test                                ISP       1  node1
node2      lvmlv22845     /dev/vgtest/lvtest                   ISP       1  node1
node2       lvmvg22895    lvmvg-vgtest                         ISP       1  node1
node2        device22910  3600000e00d0000000003312300700000-1  ISP       1  node1
node2         disk22976   3600000e00d0000000003312300700000    ISP       1  node1
node2    Global           IP-10.1.5.xx                         OSU       1  node1
node2     /test           /test                                ISP       1  node1
node2      lvmlv22845     /dev/vgtest/lvtest                   ISP       1  node1
node2       lvmvg22895    lvmvg-vgtest                         ISP       1  node1
node2        device22910  3600000e00d0000000003312300700000-1  ISP       1  node1
node2         disk22976   3600000e00d0000000003312300700000    ISP       1  node1
node2    Asia             IP-10.1.5.xx                         ISP       1  node1
node2     /test           /test                                OSU       1  node1
node2      lvmlv22845     /dev/vgtest/lvtest                   ISP       1  node1
node2       lvmvg22895    lvmvg-vgtest                         ISP       1  node1
node2        device22910  3600000e00d0000000003312300700000-1  ISP       1  node1
node2         disk22976   3600000e00d0000000003312300700000    ISP       1  node1

MACHINE  NETWORK  ADDRESSES/DEVICE           STATE  PRIO
node2    TCP      192.168.0.73/192.168.0.74  ALIVE     1
node2    TCP      192.168.1.73/192.168.1.74  ALIVE     2

待機系のサーバのLifeKeeperのステータス確認コマンド実行結果

以下は待機系のサーバのLifeKeeperのステータス確認コマンド実行結果の一例です。
以下のようにSTATEがすべて"OSU"であり、ハートビートが"ALIVE"であることが正しい状態です。

BACKUP   TAG              ID                                   STATE  PRIO  PRIMARY
------  Japan            IP-10.1.5.xx                         OSU      10  node1
------    /test           /test                                OSU      10  node1
------     lvmlv22845     /dev/vgtest/lvtest                   OSU      10  node1
------      lvmvg22895    lvmvg-vgtest                         OSU      10  node1
------       device22910  3600000e00d0000000003312300700000-1  OSU      10  node1
------        disk22976   3600000e00d0000000003312300700000    OSU      10  node1
------  Global           IP-10.1.5.xx                         OSU      10  node1
------    /test           /test                                OSU      10  node1
------     lvmlv22845     /dev/vgtest/lvtest                   OSU      10  node1
------      lvmvg22895    lvmvg-vgtest                         OSU      10  node1
------       device22910  3600000e00d0000000003312300700000-1  OSU      10  node1
------        disk22976   3600000e00d0000000003312300700000    OSU      10  node1
------  Asia             IP-10.1.5.xx                         OSU      10  node1
------    /test           /test                                OSU      10  node1
------     lvmlv22845     /dev/vgtest/lvtest                   OSU      10  node1
------      lvmvg22895    lvmvg-vgtest                         OSU      10  node1
------       device22910  3600000e00d0000000003312300700000-1  OSU      10  node1
------        disk22976   3600000e00d0000000003312300700000    OSU      10  node1

MACHINE  NETWORK  ADDRESSES/DEVICE           STATE  PRIO
node1    TCP      192.168.0.74/192.168.0.73  ALIVE     1
node1    TCP      192.168.1.74/192.168.1.73  ALIVE     2

完成したスクリプトがこちら

説明はコメントアウトにて記載します。

output=$(/opt/LifeKeeper/bin/lcdstatus -e)

#稼働系サーバ判定用にSTATEの列を抽出し、変数に格納
result01=$(echo "$output" | awk '{print $4}' | egrep -v 'ISP|ALIVE|STATE')

#待機系サーバ判定用にSTATEの列を抽出し、変数に格納
result02=$(echo "$output" | awk '{print $4}' | egrep -v 'OSU|ALIVE|STATE')

#リソース別の判定用に抽出し、変数に格納
japan=$(echo "$output" | awk 'NR>=2 && NR<=7 {print $4}')
global=$(echo "$output" | awk 'NR>=8 && NR<=13 {print $4}')
asia=$(echo "$output" | awk 'NR>=14 && NR<=19 {print $4}')

#hostname取得
hostname=$(hostname -s)

if [ "$hostname" == "待機系サーバー名01" ] || [ "$hostname" == "待機系サーバー名02" ];then
    #ホスト名が待機系サーバだった場合は以下の処理
    #$result02にISPが含まれていないことを確認する
    if [[ ! "$result02" == *"ISP"* ]]; then
      echo "Lifekeeper#2 started successfully."
    else
      echo "Lifekeeper#2 failed to started."
    fi
else
    #ホスト名が稼働系サーバだった場合は以下の処理
    #$result01にOSUが含まれていないことを確認する
    if [[ ! "$result01" == *"OSU"* ]]; then
        echo "Lifekeeper#01 started successfully."
    else
        #OSUが含まれている場合、以下の処理へ続く
        echo "Identify resources that require restart."

        #1号機のステータスにOSUが存在していた場合リソース別ステータス確認
        #japanのステータス確認
        if [[  "$japan" == *"OSU"* ]]; then
            echo "Japan restart."
        fi

        #Globalのステータス確認
        if [[  "$global" == *"OSU"* ]]; then
            echo "Global restart."
        fi

        #Asiaのステータス確認
        if [[  "$asia" == *"OSU"* ]]; then
            echo "Asia restart."
        fi
    fi
fi

テスト実施

今回は稼働系のサーバのLifeKeeperのステータス確認コマンド実行結果を元にテストし、GlobalとAsiaが再起動されるかを実験します。
実際に上位リソースの再起動をするテストはできないので、以下のメッセージが出てきたら成功とします。

Identify resources that require restart
Global restart.
Asia restart.

結果は成功!

最後に

リソースを行数で区別するという無理矢理な方法で判定しているのが個人的にモヤっとしていますが、テストでは問題なく動いたので一旦良しとしています。
他にいい方法ある方はぜひ教えていただきたいです。

この後同僚にスクリプトレビューしていただくので、修正あったらまた更新したいと思います。

Last modified: 2023-12-16

Author