🌵

【シェルスクリプト】網棚の上

2023/12/29に公開

🌵概要

世の中忘れるべきこと、そうでないものがある
これは網棚の上に置かれたまま、下車されがちな後者

🌵おまじない

set
setのオプション 役割 備考
-e スクリプト実行時にRCが0以外の時に中断 trapと併用
-u 変数未定義の際に中断
-o pipefail パイプ処理中にこけた場合、最後に異常終了したRCを返却 デフォルトは終端RCが返却
getopts

シェルスクリプトの引数を判定する際に使用するユーティリティーコマンド
シェルスクリプトのオプションに-(ハイフン)を使用することができる

trap

シェルスクリプトにて(EXIT・SIGINT)などが発生した際にエラーハンドリングを実行する
サンプルコード
SIGINT

シェル変数と環境変数を截然と扱う

シェル内で完結する変数は declare
読み込み専用変数の場合は declare -r HOGE="hoge"
シェル変数として数字で使用する場合 declare -i
環境変数として他に渡す必要があるものはdeclare -xexportを使用

関数内での変数定義はlocalを使用

シェルスクリプト内の中で、更に関数内でのみ使用する変数については local を使用
型指定はできないので、単純な使用に留める

🌵コーディング

ブレース展開

seqコマンドで連続した数字を渡す際は、ブレース{}を使用

Sample
■数字(どちらも結果は同じだが、timeコマンドで計ると、ブレース展開の方が早い)
echo {1..10}
seq 1 10
1 2 3 4 5 6 7 8 9 10

■文字列(seqではできない)
echo {a..z}
a b c d e f g h i j k l m n o p q r s t u v w x y z
exprではなく算術演算

$(()) で括ることにより、シェルで計算が行えるので、単純な計算はシェル算術を使用

Sample
■計算(どちらも結果は同じだが、timeコマンドで計ると、算術演算の方が早い)
echo $(($(sed 's/ / + /g' <<<$(echo {1..100000}))))
expr $(sed 's/ / + /g' <<<$(echo {1..100000}))
単純な判定はifを使用しない

[[]] や (()) を使用すると、簡略なif文が書ける(複雑な場合は使わない)

Sample
declare -i NUM
NUM=10
# if文
if test ${NUM} -gt 5 ; then echo "Big" ; else echo "Small" ; fi
Big
# if簡略
[[ ${NUM} -gt 5 ]] && { echo "Big" ; } || { echo "Small" ; }
Big
# ifと変数表記を簡略(数値判定のみ)
(( NUM > 5 )) && { echo "Big" ; } || { echo "Small" ; }
Big
# 算術演算はインクリメントも対応
(( NUM ++ )) && { echo ${NUM} ; }
11
関数名の先頭に_(アンダースコア)をつける

関数名を定義する際に先頭にアンダースコアを付与することで、コードの可視性の向上を計る

コーディングルールにもよるので、鵜呑みにしないこと

Sample
function _overwrite_hoge()
{
  echo "hoge" >> hoge.log
  return
}

🌵テクニック

IFS

IFS(InternalFieldSeparator)を変更する
Linux内部での区切り文字識別子

IFS確認(行末・空白・タブ・改行がデフォルト)
$ set | grep IFS
IFS=$' \t\n'
$ 

ファイル名に空白が入る場合などには、IFSから空白を削除することで一つのファイルとして扱える

read

readコマンドでインプットする際にパスワードなどを打つ際は、read -sを使う
サンプルコード

echoで色をつける

echoの色をつける方法のサンプルコード
https://github.com/Cozftro/portfolio/tree/main/shellscript/echo

🌵変数

bashで使用できる予約変数
予約変数名 役割 備考
RANDOM ランダムな数字 シェル変数 範囲は0〜32767
シェルスクリプトで使用できる予約変数
予約変数名 役割 備考
FUNCNAME 呼び出されている関数名を格納 配列 カレントの関数名は${FUNCNAME[0]}で呼ぶ
LINENO スクリプトの行数を格納 シェル変数
BASH_LINENO 呼び出し元行数を格納 シェル変数 スクリプトの関数内などで使用
SECONDS スクリプトの実行開始からの経過時間 シェル変数 秒単位でしか出力されない

Discussion