Shell-Tips

【Shell-Tips】代表的なチェック関数(英数字、数値、プロセス、ポート)を実装する。

現場のシェルスクリプトにおいて、使われる頻度の多い関数はおおよそ下記のとおりです。

  • 英数字チェック
  • 数値チェック
  • プロセスチェック
  • ポートチェック

特に規定はありませんが、「true/false」で判定される関数名には、「is〇〇」や「check〇〇」と言うように命名するのが慣例です。

その他、〇〇を取得する関数には「get〇〇」、〇〇設定する関数には「set〇〇」と言った具合です。一番最初に「動詞」を付けることで、可読性が大きく向上するためです。

チェック関数の作成

英数字チェック「isAlphaNum()」

入力された値が英数字かチェックします。

# --------------------------------------------------
# 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()

入力された値が数値かチェックします。

# --------------------------------------------------
# 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()」

プロセス実行の有無を判定します。

# --------------------------------------------------
# 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()」

ポートのリスニング有無を判定します。

# --------------------------------------------------
# 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)」を返却しています。

共通関数定義ファイルへ実装する

# 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」サービスを使用します。

#!/bin/sh
#_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
#
# ver.1.0.0 yyyy.mm.dd
#
# Usage:
#   # sh /root/scripts/bin/check.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」を実行します。

[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]#

本スクリプト利用により発生した利用者の損害全てに対し、いかなる責任をも負わないものとし、損害賠償をする一切の義務はないものとします。

よく読まれている記事

1

「私たちが日々利用しているスマートフォンやインターネット、そしてスーパーコンピュータやクラウドサービス――これらの多くがLinuxの力で動いていることをご存じですか? 無料で使えるだけでなく、高い柔軟 ...

2

Linux環境でよく目にする「Vim」という名前。サーバーにログインしたら突然Vimが開いてしまい、「どうやって入力するの?」「保存や終了ができない!」と困った経験をした人も多いのではないでしょうか。 ...

3

ネットワーク技術は現代のITインフラにおいて不可欠な要素となっています。しかし、ネットワークを深く理解するためには、その基本となる「プロトコル」と「レイヤ」の概念をしっかり把握することが重要です。 こ ...

4

この記事は、Linuxについて勉強している初心者の方向けに「Shellスクリプト」について解説します。最後まで読んで頂けましたら、Shellスクリプトはどのような役割を担っているのか?を理解出来るよう ...

5

Javaは世界中で広く使われているプログラミング言語であり、特に業務システムやWebアプリケーションの開発において欠かせない存在です。本記事では、初心者向けにJavaの基礎知識を網羅し、環境構築から基 ...

-Shell-Tips