ShellScript
Bash
shellcheck

ShellScriptの不具合やエラーの原因がわからないときに便利! 静的コード解析ツール ShellCheck

まずはインストール

$ brew install shellcheck

使い方

$ shellcheck ファイル名

実際に使ってみました!

解析するコード

test.sh
#!/bin/bash

readonly SCRIPT_NAME=${0##*/}

touch_file10()
{

    local fileName="$1"
    touch "$fileName"{1..10}.txt
}

if [[ $# < 0 ]]; then
    printf '%s\n' "${SCRIPT_NAME}: 引数にファイル名を指定してください!" 1>&2
    exit 1
fi


touch_file10 "$1"

引数として入力された値をファイル名とし10ファイル、テキストファイルを作ります。
引数が指定されていない時、つまり引数の個数が0の時は処理を終了します。

いざこのコードを引数なしで実行すると、

printf '%s\n' "${SCRIPT_NAME}: 引数にファイル名を指定してください!" 1>&2
exit 1

上記コードは実行されず、1.txt,2txt,3txt……と10ファイル作成されます。:thinking:

ではここで、ShellCheckをつかってみます。

shellcheck test.sh

すると以下のように表示されました。

$ shellcheck test.sh

In test.sh line 15:
if [[ $# < 0 ]]; then
         ^-- SC2071: < is for string comparisons. Use -lt instead.

<は文字列に関する演算子ですよ! って表示されました。
ついつい他の言語の癖で比較に<を使ってしまいがちですが、
bashでは<は文字列に関する演算子で 以下のような意味になるんです!

str1 < str2 # str1がstr2よりも辞書順で前にある

今回の場合だと、整数に関する演算子を使う必要があるってことなんです!:relaxed:
shellcheckの内容をもとに以下のように修正。

# 引数の個数が0以下の場合、処理を止めたいので、-leをつかいます。
if [[ $# -le 0 ]]; then
    printf '%s\n' "${SCRIPT_NAME}: 引数にファイル名を指定してください!" 1>&2
    exit 1
fi

これで引数が0の時は処理を実行させずにexitできました!
このようにshellscriptを書いた際には、一度shellcheckを挟むことで、エラーや不具合を見つけれるでしょう!:eyeglasses:

なお、今回の例だと
https://github.com/koalaman/shellcheck/wiki/SC2071
と検索するとより詳しい解説を確認することができます!

ちなみに、alfredで以下のように設定するとエラーコードの検索が楽になります!

s001.png

ターミナルからエラーコードをコピーして
ペーストするだけ。
スクリーンショット 2018-02-01 23.07.15.png

ではまた!