これは、なにをしたくて書いたもの?
タイトル通り。
シェルスクリプトの静的解析ツールである、ShellCheckをUbuntu Linux 20.04 LTSにインストールしてみます。
ShellCheck
ShellCheckとは、シェルスクリプトの静的解析ツールです。
ShellCheck – shell script analysis tool
GitHub - koalaman/shellcheck: ShellCheck, a static analysis tool for shell scripts
現時点での最新バージョンは、0.9.0です。
オンラインでも使えるようで、ランダムなサンプルからどういうものか確認することができます。
利用形態としては、オンライン(Web)、CLI、エディターとのインテグレーション、CIとのインテグレーションといった感じですね。
チェック内容は、このあたりに書かれています。
ShellCheck / Gallery of bad code
Home · koalaman/shellcheck Wiki · GitHub
チェック内容の完全な内容も、Wikiにあるようです。
Checks · koalaman/shellcheck Wiki · GitHub
一覧そのものを見るには、こちらからたどるか、GitHub Wikiのページを展開するしかなさそうです。
Enumerated shellcheck codes https://github.com/koalaman/shellcheck/wiki/Checks · GitHub
チェック内容それぞれにページがあります。
SC1000 · koalaman/shellcheck Wiki · GitHub
では、簡単に試してみましょう。
環境
今回の環境は、こちら。Ubuntu Linux 20.04 LTSです。
$ lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 20.04.5 LTS Release: 20.04 Codename: focal $ uname -srvmpoi Linux 5.4.0-135-generic #152-Ubuntu SMP Wed Nov 23 20:19:22 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux
ShellCheckをインストールする
まずは、ShellCheckをインストールしましょう。
Debianベースのディストリビューションの場合は、apt
でインストールできるみたいです。
$ sudo apt install shellcheck
確認。
$ shellcheck --version ShellCheck - shell script analysis tool version: 0.7.0 license: GNU General Public License, version 3 website: https://www.shellcheck.net
インストールされたのは、0.7.0ですね。少し古いみたいです。
ヘルプを確認。
$ shellcheck --help Usage: shellcheck [OPTIONS...] FILES... -a --check-sourced Include warnings from sourced files -C[WHEN] --color[=WHEN] Use color (auto, always, never) -i CODE1,CODE2.. --include=CODE1,CODE2.. Consider only given types of warnings -e CODE1,CODE2.. --exclude=CODE1,CODE2.. Exclude types of warnings -f FORMAT --format=FORMAT Output format (checkstyle, diff, gcc, json, json1, quiet, tty) --list-optional List checks disabled by default --norc Don't look for .shellcheckrc files -o check1,check2.. --enable=check1,check2.. List of optional checks to enable (or 'all') -P SOURCEPATHS --source-path=SOURCEPATHS Specify path when looking for sourced files ("SCRIPTDIR" for script's dir) -s SHELLNAME --shell=SHELLNAME Specify dialect (sh, bash, dash, ksh) -S SEVERITY --severity=SEVERITY Minimum severity of errors to consider (error, warning, info, style) -V --version Print version information -W NUM --wiki-link-count=NUM The number of wiki links to show, when applicable -x --external-sources Allow 'source' outside of FILES --help Show this usage summary and exit
今回は、このまま使うことにします。
ShellCheckを使う
ShellCheckはシェルスクリプトの静的解析ツールなので確認対象のシェスクリプトが必要になりますが、これはShellCheckのWebサイトで
ランダムに提示されるスクリプトをそのまま使うことにしました。
sample.sh
#!/bin/bash ## Example: ShellCheck can detect many different kinds of quoting issues if ! grep -q backup=true.* "~/.myconfig" then echo 'Backup not enabled in $HOME/.myconfig, exiting' exit 1 fi if [[ $1 =~ "-v(erbose)?" ]] then verbose='-printf "Copying %f\n"' fi find backups/ \ -iname *.tar.gz \ $verbose \ -exec scp {} “myhost:backups” +
確認。
$ shellcheck sample.sh In sample.sh line 4: if ! grep -q backup=true.* "~/.myconfig" ^-----------^ SC2062: Quote the grep pattern so the shell won't interpret it. ^---------^ SC2088: Tilde does not expand in quotes. Use $HOME. In sample.sh line 6: echo 'Backup not enabled in $HOME/.myconfig, exiting' ^-- SC2016: Expressions don't expand in single quotes, use double quotes for that. In sample.sh line 10: if [[ $1 =~ "-v(erbose)?" ]] ^-----------^ SC2076: Don't quote right-hand side of =~, it'll match literally rather than as a regex. In sample.sh line 12: verbose='-printf "Copying %f\n"' ^----------------------^ SC2089: Quotes/backslashes will be treated literally. Use an array. In sample.sh line 16: -iname *.tar.gz \ ^------^ SC2061: Quote the parameter to -iname so the shell won't interpret it. ^-- SC2035: Use ./*glob* or -- *glob* so names with dashes won't become options. In sample.sh line 17: $verbose \ ^------^ SC2090: Quotes/backslashes in this variable will not be respected. ^------^ SC2086: Double quote to prevent globbing and word splitting. Did you mean: "$verbose" \ In sample.sh line 18: -exec scp {} “myhost:backups” + ^-- SC1110: This is a unicode quote. Delete and retype it (or quote to make literal). ^-- SC1110: This is a unicode quote. Delete and retype it (or quote to make literal). For more information: https://www.shellcheck.net/wiki/SC2076 -- Don't quote right-hand side of =~... https://www.shellcheck.net/wiki/SC1110 -- This is a unicode quote. Delete a... https://www.shellcheck.net/wiki/SC2061 -- Quote the parameter to -iname so ...
オンラインでの実行結果と同様の内容が検出されました。
設定方法は?ということですが、コメントでいろいろ書くようです。ホームディレクトリに.shellcheckrc
というファイルを作成する方法も
あるようです。
Directive · koalaman/shellcheck Wiki · GitHub
特定のルールを無視する場合は、コメントで書くか、オプションで指定するか、.shellcheckrc
に書くかといった感じですね。
Ignore · koalaman/shellcheck Wiki · GitHub
オプションで指定してみましょう。-e
で指定します。
$ shellcheck -e SC2016 sample.sh
複数指定する場合は、,
区切りで良いみたいです。-e
オプションを繰り返しても動作しましたが。
$ shellcheck -e SC2016,SC1110 sample.sh $ shellcheck -e SC2016 -e SC1110 sample.sh
Flycheckに組み込む
ShellCheckは、EmacsのFlycheckに組み込むことができるようです。
Flycheck — Syntax checking for GNU Emacs — Flycheck 33-cvs documentation
といっても、shellcheck
コマンドにパスが通っていて、Flycheckがインストールされていればすぐに使えるようになりますが。
こんな感じですね。