現場でのシェルについて(2)

アイキャッチ画像

この記事では、現場でのシェルについて(1)に続き、シェルスクリプトの作り方やシェル操作のコマンドについてご紹介します。

シェルスクリプト(test.sh)の作り方

(1)作成

  • vi [shを置きたい場所]/test.sh
  • viエディタが開くので、コード(処理)を記載
  • Escキーでコマンドモードへ移行、「:⇒wq」の順押下でviエディターを保存して閉じる

(2)シェルスクリプト実行

bash [shを置きたい場所]/test.sh
または
bash -x [shを置きたい場所]/test.sh
※ -xオプションを付けることで、処理の過程が表示できます(変数にどんな値が入っているかなど)。
※基本的に現場でのシェルスクリプトの証跡は”-x”を付与したモノになります。 

学習6:権限変更について(chmod / chown)

権限(パーミッション)はシステム構築や運用、保守において頻繁に使用されます。もし、特定のディレクトリやファイルが「存在するのに参照・編集できない」などの状態であれば、まず、その対象の権限を確認して、必要に応じてchmod/chownで変更します。

【参考:権限について】
https://www.infraeye.com/study/linuxz26.html

確認方法

lsコマンドを実行し、フィールド1(-rwx〜) と フィールド3(yamadatak:tecnication)を確認します。
(※スペースや空白、カンマなどで区切られた項目はフィールドと呼ばれたりします)

ディレクトリ:ls -ld ディレクトリ名
drwxr-xr-x 1 yamadatak:tecnication ファイルサイズ 月日 時間 /work/test/
⇒一番左端の”d”はディレクトリを意味しています。

権限を数字にすると755 / 所有者は山田、グループはテクニケーション
⇒山田はこのディレクトリの中に対し、読書実行が出来ますが、それ以外のユーザーは読込と実行しかできません。

(lsは出来るが、ファイルを作ったり、編集したりが出来ない)
ファイル:ls -l ファイル名
-rwx—— 1 yamadatak:tecnication ファイルサイズ 月日 時間 /work/test/test.txt
⇒権限を数字にすると700 。
⇒山田以外はこのファイルに対して、読むことすらできません。

chmod/chown コマンドの詳細については下記URLが分かりやすりかと思います。どちらも色々とオプションはありますが、-R(再帰的:指定したディレクトリ配下全ての権限変更)くらいしか使われないかなと思います。

chmod:権限変更

主な実行方法には「(1)数字を指定」「(2)アルファベットで明示的に指定」のパターンが存在しますが、現場においては「(1)数字を指定」のケースが多いです((2)はあまり見たことがありません)。

chmod 755 ファイル名
chmod a=xwr,g-x,o-xw ファイル名

chown:所有者変更

よく使われるのは下記になります。

chown 所有者名 ファイル名またはディレクトリ名
⇒所有者のみ変更

chown 所有者名:グループ名 ファイル名またはディレクトリ名
⇒グループ名のみ変更したい場合は、chgrpコマンドを使います。
chgrp グループ名 ファイル名またはディレクトリ名

補足

mkdir コマンドにて -m オプションを使用すると、権限を指定して作成する事ができます。
mkdir -m 644 /work/test2

学習7:シバン

『学習2』でも触れたので省略します。
※シェルスクリプトは1行目に「シバン」と呼ばれる、そのシェルスクリプトが使用する言語のパスを記入します。

何の言語(usr/bin/bashだったり、/bin/shだったり、bi/kshだったり)、これについては、実際に参画する現場のプログラムを見て、最初に確認しておくと良いかと思います。

学習8:コメントアウト(#)について

システムの運用ツール(シェルスクリプト)の作成として、よく使用します。行頭に”#”を記述する事で、その行はシェルスクリプト実行時に処理されません。

主な使用方法は以下の通りです。

(1)シェルスクリプトのラベル
(2)シェルスクリプト内のメモ
(3)製造やテスト時、rmコマンド等の一歩間違えれば危険なコマンドをコメントアウトで一時的に処理させなくする

(1)ラベルについて

シェルスクリプトの冒頭数行くらいを使用して、シェルスクリプトの情報(スクリプト名、処理概要、引数等)を記載します。ラベルはプロジェクトごとにルール等があるので、実際の現場で他のスクリプトを参考にすると良いです。

<例>

!/bin/sh

######################################################

#

# スクリプト名:〇〇〇.sh

# スクリプト名(和名):なんちゃら機能

# 処理概要:指定したサーバに対し、なんちゃらする。

# 実行方法

# 〇〇〇.sh $1 $2 $3

# 引数

# $1:サーバ名

# $2:必要なパラメータ1(何の処理をするかを判定等)

# $3:必要なパラメータ2(バックアップとるか取らないかを指定等)

#

######################################################

以降はメイン処理を記載します。

(2)シェルスクリプト内のメモについて

「スクリプトが見づらくなるからコメントはいらない!」という意見もあったりしますが、ややこしい個所は基本的にはどんどん入れた方が良いと思います。
※それでも長文はNG(端的にお願いします)

少なくとも、ブロック単位(初期処理、〇〇処理、△△処理、終了処理)の工程ごとにコメントで区切ると見やすくて良いです。このあたりもプロジェクトごとにルールがありますので、既存スクリプトを参考にしてください。

<例>

#—————————————————

# 初期処理(パラメータチェック)

#—————————————————

# サーバ名チェック

if [ ${SERVER} != “TECSRV11”] ;then

    echo “このサーバはテクニサーバじゃないです”

fi

#—————————————————

# 〇〇処理

#—————————————————

#省略

#—————————————————

# △△処理

#—————————————————

#省略

#—————————————————

# 終了処理処理

#—————————————————

# 問題があれば異常終了 

if [ ${RETCODE} -eq 0] ;then

    exit 0

else

    exit 99

fi

(3)製造やテスト時、rmコマンド等の一歩間違えれば、危険なコマンドをコメントアウトで一時的に処理させなくする

rm -f ${TEST_DIR}/*
⇒上記は${TEST_DIR}の中にあるファイルを全て削除するコマンドです。

製造やテストの段階でもしも、${TEST_DIR}の値が取得出来ず、空白の値となっている場合、このコマンドは下記のように判断され、処理されます。

rm -f /*

⇒これは「ルート配下のファイルを全て削除する」と言うサーバー破壊に等しいコマンドになります。基本的にrootユーザでなければ削除されることはありませんが、万が一ということはありますので、シェルスクリプト製造段階では、一旦rmコマンドをコメントアウトするのが安心かと思います。

こう言うのがあるので、なるべく「*のみ」は使いたくないんですけどね…。削除するファイル名が決まっている場合には、指定してあげると安心です。

rm -f ${TEST_DIR}/*.dat(.datファイルのみ削除、TEST_DIRが空白でも全破壊にはならない)
とか
rm -f ${TEST_DIR}/TESTLOG_*(ファイル名がTESTLOGで始まるものだけを削除)

学習9:echo について

前回の『学習3』でも記載してるので省略します。

学習10:変数について

変数は以下の2種類が存在します。簡単にいうと下記の通りです。

(1)環境変数:そのサーバ内で予め定義されている変数

(2)シェル変数:シェルスクリプト実行中でのみ定義される変数

【参考サイト】
https://qiita.com/chihiro/items/bb687903ee284766e879

(1)環境変数

よく設定に使うコマンドは下記になります。

export MYNAME=”RAOU”
⇒環境変数「MYNAME」を設定し、RAOUという値を定義しました。

この状態でechoで確認すると下記の通りです。
echo “${MYNAME}”
RAOU

※注意:コマンドによって定義した環境変数はそのセッションを切断(teratarmを閉じる等)すると、定義した変数ごと消えますので、また定義する必要があります。対策としては~/.bash_profileの編集が必要になりますが、おそらくそれはサーバー設計の範囲になると思うので、現段階は不要かと思います。

(2)シェル変数

シェルスクリプト実行中のみ定義・使用される変数です。実行終了後にenvコマンドやsetコマンドで確認しても、表示されません。

シェルスクリプト内では基本的にexportはではなく、下記のような設定方法になります。

MYNAME=”TOKI”

学習11:ifについて

シェルスクリプトの作成において最も重要で、必要不可欠な処理になります。そのため、書き方や比較演算子・文字列/ファイルチェックは、すぐに確認できるように、役に立つサイトはブックマークをしておくと良いと思います。

こればかりは現場の設計によるので、基本をおさえつつ、設計にマッチする分岐・比較演算を選択していきます。ここでは、基本的な書き方と比較演算子(数値/文字列/ファイル)を簡単に説明します。

【参考サイト:基本】
【シェルスクリプト】条件分岐させるifの使い方! (eng-entrance.com)

【参考サイト:比較演算子/文字列】
初心者向け!シェルスクリプト演算子まとめました【Linux】 (eng-entrance.com)

(1)基本的な書き方(2分岐)

if [ ${TEST_NAME} = “KENSIRO” ] ;then

    # KENSIROの場合の処理

    echo “おれはケンシロウ”

else 

    # KENSIRO以外の処理

    echo “エラーです”

fi

(2)基本的な書き方(3分岐)

if [ ${TEST_NAME} = “KENSIRO” ] ;then

    # KENSIROの場合の処理

    echo “おれはケンシロウ”

elif [ ${TEST_NAME} = “RAOU” ] ;then

    # RAOUの場合の処理

    echo “我は拳王”

else 

    # KENSIRO、RAOU以外の処理

    echo “エラーです”

fi

⇒分岐が増えると分かりづらくなる可能性もあるため、プロジェクトによっては、〇分岐以上はcaseコマンドを使用する。といったルールもある(私もcaseの方が分かりやすいかなと)。

https://shellscript.sunone.me/case.html

上記をcase化すると、下記のような感じになります。

      case ${TEST_NAME} in

          # KENSIROの場合の処理

          KENSIRO ) echo “おれはケンシロウ” ;;

          # RAOUの場合の処理

          RAOU )  echo “我は拳王” ;;

          # # KENSIRO、RAOU以外の処理

          * ) echo “エラーです” ;;

      esac

数値:よく使う演算子

-eq , -ne :主に直前の処理の戻り値を確認に使用
それ以外:パラメータ数チェックなどで使用

文字列:よく使う演算子

(1)-n 文字列 : 値が入ってれば真

<例:TEST_NAMEに値が入っていれば次のif ${TEST_NAME} = “KENSIRO”に進みます。入ってなければスルー>

if [ -n ${TEST_NAME}] ;then

    if [ ${TEST_NAME} = “KENSIRO” ] ;then

        # KENSIROの場合の処理

        echo “おれはケンシロウ”

    else

        echo “エラーです”

    fi

fi

(2)-z 文字列:値が入っていなければ真

<例:TEST_NAMEに値が入っていなければエラー>

if [ -z ${TEST_NAME}] ;then

        echo “エラーです、名を名乗ってください”

fi

ファイル:よく使う演算子

(1)-d ディレクトリなら真

<例>

TEST_DIR=/home/TEST/work

if [ -d ${TEST_DIR}] ;then

        echo “TEST_DIRはディレクトリです(TEST_DIR=${TEST_DIR})”

fi

⇒実行結果

  TEST_DIRはディレクトリです(TEST_DIR=${/home/TEST/work})

※補足 

“!”を付与することで、否定形になります。(TEST_DIRがディレクトリで無ければ真)

TEST_DIR=/home/TEST/work/test.txt

if [ ! -d ${TEST_DIR}] ;then

        echo “エラーです、ディレクトリではありません”

fi

(2)-f ファイルなら真

基本的に上記ディレクトリ(-d)と考え方は同じです。