現場のシェルスクリプトにおいて、使われる頻度の多い関数はおおよそ下記のとおりです。
- 英数字チェック
- 数値チェック
- プロセスチェック
- ポートチェック
特に規定はありませんが、「true/false」で判定される関数名には、「is〇〇」や「check〇〇」と言うように命名するのが慣例です。
その他、〇〇を取得する関数には「get〇〇」、〇〇設定する関数には「set〇〇」と言った具合です。一番最初に「動詞」を付けることで、可読性が大きく向上するためです。
チェック関数の作成
英数字チェック「isAlphaNum()」
入力された値が英数字かチェックします。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
# -------------------------------------------------- # Check the value contains only alphanumeric or not. # -------------------------------------------------- # param1 value # return 0:alnum 1:not alnum # -------------------------------------------------- isAlphaNum() { val="$(echo $1 | sed -e 's/[^[:alnum:]]//g')" if [ "$val" != "$1" ]; then return 1 fi return 0 } |
正規表現「alnum」を使用して、引数「$1」を英数字へ置換しています。置換後の値と引数の値が一致しない場合「1(false)」を返却、一致すれば「0(true)」を返却します。
数値チェック「isNumeric()」
入力された値が数値かチェックします。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
# -------------------------------------------------- # Check the value is some number or not. # -------------------------------------------------- # param1 value # return 0:numeric 1:other # -------------------------------------------------- isNumeric() { expr "$1" + 1 >/dev/null 2>&1 if [ $? -ge 2 ]; then return 1 fi return 0 } |
関数内部で引数「$1」へ数値の「1」を加算しています。失敗すれば数値ではないと判断出来る為「1(false)」を返却、成功した場合は「0(true)」を返却しています。
プロセスチェック「isProcAlive()」
プロセス実行の有無を判定します。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
# -------------------------------------------------- # Check the keyword is in process table or not. # -------------------------------------------------- # param1 specify the process keyword you want to check # return 0:is in process table 1:could not find # -------------------------------------------------- isProcAlive() { cnt=`ps auxw | grep $1 | grep -v grep | grep -v $SCRIPT_NAME | wc -l` if [ $cnt -eq 0 ]; then return 1 fi return 0 } |
「ps」コマンドで引数「$1」にマッチしたプロセスを抜き出し、その中から「grep -v(除外)」コマンドで「grep」コマンド自体のプロセス及び「$SCRIPT_NAME(実行シェル)」のプロセスを除外しています。最後に抽出した行数をカウントして、0なら「1(false)」を返却、0以外の場合は「0(true)」を返却しています。
ポートチェック「isPortAlive()」
ポートのリスニング有無を判定します。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
# -------------------------------------------------- # Check the port is listening or not. # -------------------------------------------------- # specify the port number you want to check # return 0:listening 1:closed # -------------------------------------------------- isPortAlive() { cnt=`netstat -tan | grep ":$1" | grep -w 'LISTEN' | wc -l` if [ $cnt -eq 0 ]; then return 1 fi return 0 } |
「netstat」コマンドで通信中の情報の中から引数「$1」にマッチしたポート番号を抜き出し、その中から「grep -w(単語検索)」で一致する文字列「LISTEN」を抽出しています。最後に抽出した行数をカウントして、0なら「1(false)」を返却、0以外の場合は「0(true)」を返却しています。
共通関数定義ファイルへ実装する
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
# shell scripts common resource #_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ # # common.shrc ver.1.0.0 2020.04.24 # # Usage: # -------- # # Description: # 各種機能より呼び出される共通機能を実装する。 # # 設計書 # none # #_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ # ------------------------------------------------------------ # Constant declaration(定数の宣言領域) # ------------------------------------------------------------ BASE_PATH=${BASE_PATH:-"/root/scripts"} COM_PATH=${BASE_PATH}/com ETC_PATH=${BASE_PATH}/etc LOG_PATH=${BASE_PATH}/log TMP_PATH=${BASE_PATH}/tmp REP_PATH=${BASE_PATH}/rep SCRIPT_NAME=`basename $0` JOB_OK=0 JOB_WR=1 JOB_ER=2 MSG_CONF=${ETC_PATH}/message.conf # ------------------------------------------------------------ # functions (関数を記述する領域) # ------------------------------------------------------------ (省略)前回までの関数が記述されている領域 # -------------------------------------------------- 👈 ここから追記 # Check the value contains only alphanumeric or not. # -------------------------------------------------- # param1 value # return 0:alnum 1:not alnum # -------------------------------------------------- isAlphaNum() { val="$(echo $1 | sed -e 's/[^[:alnum:]]//g')" if [ "$val" != "$1" ]; then return 1 fi return 0 } # -------------------------------------------------- # Check the port is listening or not. # -------------------------------------------------- # param1 value # return 0:listening 1:closed # -------------------------------------------------- isPortAlive() { cnt=`netstat -tan | grep ":$1" | grep -w 'LISTEN' | wc -l` if [ $cnt -eq 0 ]; then return 1 fi return 0 } # -------------------------------------------------- # Check the keyword is in process table or not. # -------------------------------------------------- # param1 specify the process keyword you want to check # return 0:is in process table 1:could not find # -------------------------------------------------- isProcAlive() { cnt=`ps auxw | grep $1 | grep -v grep | grep -v $SCRIPT_NAME | wc -l` if [ $cnt -eq 0 ]; then return 1 fi return 0 } # -------------------------------------------------- # Check the port is listening or not. # -------------------------------------------------- # return 0:listening 1:closed # -------------------------------------------------- isPortAlive() { cnt=`netstat -tan | grep ":$1" | grep -w 'LISTEN' | wc -l` if [ $cnt -eq 0 ]; then return 1 fi return 0 } |
実行シェルスクリプトの作成
チェック関数確認用に「httpd」サービスを使用します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 |
#!/bin/sh #_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ # # ver.1.0.0 yyyy.mm.dd # # Usage: # # sh /root/scripts/bin/func.sh # # Description: # 例題コマンド実行スクリプト # # 設計書 # なし # #_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ . `dirname $0`/../com/comFunc.shrc # ---------------------------------------------------------- # variables (変数の宣言領域) # ---------------------------------------------------------- scope="var" rc=${JOB_ER} # ---------------------------------------------------------- # functions (関数を記述する領域) # ---------------------------------------------------------- scope="func" # -------------------------------------------------- # devider. # -------------------------------------------------- # return N/A # -------------------------------------------------- line (){ echo -e "\\n ------------" echo -e " ▼ ${1}" } # ---------------------------------------------------------- # pre-process (事前処理ロジックを記述する領域) # ---------------------------------------------------------- scope="pre" startLog # Set a trap. trap abort 1 2 3 15 # ---------------------------------------------------------- # main-process (メインロジックを記述する領域) # ---------------------------------------------------------- scope="main" # 英数字チェック「isAlphaNum()」👈 英数字チェック line "isAlphaNum()" var="ab123" if isAlphaNum ${var} ; then logOut "[ ${var} ]は、英数字です。" else logOut "[ ${var} ]は、英数字ではありません。" fi # 数値チェック「isNumeric()」👈 数値チェック line "isNumeric" var="12345" if isNumeric ${var} ; then logOut "[ ${var} ]は、数値です。" else logOut "[ ${var} ]は、数値ではありません。" fi # プロセス起動/停止チェック「isProcAlive()」👈 プロセス起動/停止チェック line "isProcAlive()" var="httpd" if isProcAlive ${var} ; then logOut "[ ${var} ]は、起動中です。" else logOut "[ ${var} ]は、停止中です。" fi # ポートチェック「isPortAlive()」👈 ポートチェック line "isPortAlive()" var="80" if isPortAlive ${var} ; then logOut "[${var}]を、リスニング中です。" else logOut "[${var}]を、リスニングしていません。" fi if [ $? -eq ${JOB_OK} ]; then rc=${JOB_OK} fi # ---------------------------------------------------------- # post-process (事後処理ロジックを記述する領域) # ---------------------------------------------------------- scope="post" exitLog ${rc} |
[実行結果]
例として「httpd」プロセスを起動して、シェルスクリプト「check.sh」を実行します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
[root@CentOS7 bin]# sh check.sh [root@CentOS7 bin]# cd ../log [root@CentOS7 log]# cat check.log 2020-05-13 16:56:08 [ pre ] SCRIPT:[ check.sh ] PID:[ 11135 ] STARTED LOG. ------------ ▼ isAlphaNum() 2020-05-13 16:56:08 [ main ] [ ab123 ]は、英数字です。 ------------ ▼ isNumeric 2020-05-13 16:56:08 [ main ] [ 12345 ]は、数値です。 ------------ ▼ isProcAlive() 2020-05-13 16:56:08 [ main ] [ httpd ]は、起動中です。 ------------ ▼ isPortAlive() 2020-05-13 16:56:08 [ main ] [80]を、リスニング中です。 2020-05-13 16:56:08 [ post ] SCRIPT:[ check.sh ] PID:[ 11135 ] ENDED LOG with NOMAL. [root@CentOS7 log]# |
※ 本スクリプト利用により発生した利用者の損害全てに対し、いかなる責任をも負わないものとし、損害賠償をする一切の義務はないものとします。