Bash
shell
コーディング規約
More than 1 year has passed since last update.

bashコーディング規約

モチベーション

  • 一定の品質を保ちたい
  • 書くたびに書き方が変わるのは好ましくない

シェバング(shebang)は#!/bin/shではなく#!/bin/bashにする

  • シバン、シェバンとも言われる
  • #!/bin/shは実行環境によって様々なシェルにシンボリックリンクになっているので、bashなら#!/bin/bashと明示しよう
#!/bin/bash

インデントは半角スペース2つ

  • 1行が横に長くなり折り返されないように

処理内容および使い方をスクリプト内に記載する(usage()

  • 何をしてくれるスクリプトか、どのように使うのかusage()関数を用意しよう
    • ヘッダコメントでもいいけど
function usage() {
cat <<_EOT_
Usage:
  $0 [-a] [-b] [-f filename] arg1 ...

Description:
  hogehogehoge

Options:
  -a    aaaaaaaaaa
  -b    bbbbbbbbbb
  -f    ffffffffff

_EOT_
exit 1
}

オプション解析を行う(getopts

#!/bin/bash

function usage() {
cat <<_EOT_
Usage:
  $0 [-a] [-b] [-f filename] arg1 ...

Description:
  hogehogehoge

Options:
  -a    aaaaaaaaaa
  -b    bbbbbbbbbb
  -f    ffffffffff

_EOT_
exit 1
}

if [ "$OPTIND" = 1 ]; then
  while getopts abf:h OPT
  do
    case $OPT in
      a)
        FLAG_A="on"
        echo "FLAG_A is $FLAG_A"            # for debug
        ;;
      b)
        FLAG_B="on"
        echo "FLAG_B is $FLAG_B"            # for debug
        ;;
      f)
        ARG_F=$OPTARG
        echo "ARG_F is $ARG_F"              # for debug
        ;;
      h)
        echo "h option. display help"       # for debug
        usage
        ;;
      \?)
        echo "Try to enter the h option." 1>&2
        ;;
    esac
  done
else
  echo "No installed getopts-command." 1>&2
  exit 1
fi

echo "before shift"                       # for debug
shift $((OPTIND - 1))
echo "display other arguments [$*]"       # for debug
echo "after shift"                        # for debug

変数の命名規則

定数はreadonly宣言する

定数は大文字、定数以外は小文字

readonly CONSTANT_PARAM="hoge"
score=100

複数単語の場合は「名詞」と「名詞」を_で結合

readonly MAX_NUMBER=100

ローカル変数の先頭に_を付ける

function cal_score_ave() {
  local _score_sum=0
  # ...
}

ファイルおよびディレクトリの命名規則

  • 末尾に/をつけない
  • readonly宣言して定数にする
対象 命名規則 備考
ファイル名(絶対パス) HOGE_FILE
ディレクトリ名(絶対パス) HOGE_DIR
ファイル名(パスなし) HOGE_FILENAME
ディレクトリ名(パスなし) HOGE_DIRNAME
# ファイル名(絶対パス)
readonly HOGE_FILE="/var/tmp/hoge.txt"
# ディレクトリ名(絶対パス)
readonly HOGE_DIR="/var/tmp/hoge"
# ファイル名(パスなし)
readonly HOGE_FILENAME="hoge.txt"
# ディレクトリ名(パスなし)
readonly HOGE_DIRNAME="hoge"

変数の宣言箇所

値を変更する可能性のある場合は冒頭に

  • あとで値を変更する場合にわかりやすい

値を変更せず内部的に利用する場合は利用する箇所の直前に

  • 変数と処理の関連性がわかりやすい

関数の命名規則

function宣言する

小文字で「動詞」と「名詞」を_で結合

  • usage()は例外
function cal_score_ave() {
  # ...
  return 0
}

関数は必ずreturnする

function cal_score_ave() {
  # ...
  return 0
}

リターンコード:正常終了は0、異常終了は0以外

パイプの前後に半角スペース1つ

CMD1 | CMD2

リダイレクトの前は半角スペース1つ、後はスペースなし

CMD1 >hoge.txt
CMD1 >>hoge.txt
CMD2 <fuga.txt
CMD2 <<fuga.txt

リダイレクトはグルーピングする

{
  echo "hoge"
  echo "fuga"
  echo "piyo"
} >>logfile.log

制御構文

ifthenは同一行に、セミコロンの後ろは半角スペース1つ

if [ $? -ne 0 ]; then
  # ...
  exit 1
fi

forwhiledodoneを揃える

for _score in ${SCORE_ARRAY[@]}
do
  _score_sum=$((_score_sum + _score))
done
while IFS=$`\n` read _line
do
  echo $_line
done <hoge.txt

if文を省略しない

[ $hoge = $foo ] && echo "true" || echo "false"

参考情報

  1. シェルスクリプト Tips
  2. bash によるオプション解析
  3. 逆引きシェルスクリプト/getoptsを利用して引数を取得する(bashビルドイン)