シェルスクリプトは、自由度が高く大変便利なものですが、自分のクセで良くない使い方をしてしまっていたりします。それらの間違いを指摘してくれる便利なツール(shellcheck)で、悪いクセを直しましょう。
検証した環境
$ cat /etc/os-release
PRETTY_NAME="Debian GNU/Linux 11 (bullseye)"
NAME="Debian GNU/Linux"
VERSION_ID="11"
VERSION="11 (bullseye)"
VERSION_CODENAME=bullseye
ID=debian
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"
$ uname -r
5.15.56-v8+
shellcheckの導入
aptを使用してインストールすることが出来ます。バージョンは少し古めです。(2022/10/03時点)
$ sudo apt install shellcheck
$ shellcheck --version
ShellCheck - shell script analysis tool
version: 0.7.1
license: GNU General Public License, version 3
website: https://www.shellcheck.net
検証用シェルスクリプト
実際にシェルスクリプトを用意して、動作検証をしてみます。
誤りのあるシェルスクリプト
いまどき、exprなんて使わないでしょうが、下記のシェルスクリプトを用意しました。
$ cat test.bash
#!/bin/bash
COUNT=1
END_COUNT=3
while [ "${COUNT}" -le "${END_COUNT}" ] ; do
echo ${COUNT}
COUNT=$(expr "${COUNT}" + 1)
done
$ ./test.bash
1
2
3
作成したシェルスクリプトをチェックしてみます。
$ shellcheck test.bash
In test.bash line 7:
COUNT=$(expr "${COUNT}" + 1)
^--^ SC2003: expr is antiquated.
Consider rewriting this using $((..)), ${} or [[ ]].
For more information:
https://www.shellcheck.net/wiki/SC2003 -- expr is antiquated. Consider rewr...
文法的には良くないとのこと。
exprを使うのは時代遅れ。${}または[[ ]]、$((..))を使え。とのこと。
正しいシェルスクリプト
shellcheckで指摘された部分を、指示通りに修正したのが、下記のシェルスクリプトです。
$ cat test.bash
#!/bin/bash
COUNT=1
END_COUNT=3
while [ "${COUNT}" -le "${END_COUNT}" ] ; do
echo ${COUNT}
COUNT=$(("${COUNT}" + 1))
done
$ ./test.bash
1
2
3
もう一度、シェルスクリプトをチェックしてみると、今度は、何も指摘されませんでした。
$ shellcheck test.bash
捕捉 8進数の扱いとされてしまう場合
$ X=08 ・・・ 定数の先頭に「0」があると、8進数の扱いになる
$ echo $(expr ${X} + 1) ・・・ exprでは解釈されない
9
$ echo $((${X} + 1)) ・・・ そのまま計算すると、8進数として取り扱うためエラーとなる
-bash: 08: value too great for base (error token is "08")
$ echo $((1 + 10#${X})) ・・・ このように書くと、10進数として取り扱われる
9