
ShellCheckは、Bashを中心としたシェルスクリプトの構文解析と挙動検査を行うオープンソースの静的解析ツールである。ノルウェー在住のVidar Holen氏が2012年に開発を始め、Haskellで実装されている点が一風変わっている。シェルスクリプトは、わずかな書き間違いが実行時に致命的なバグへ化けやすく、しかも警告を出してくれる仕組みがほとんどない歴史を持つ。ShellCheckは、長年エンジニアたちが踏み抜いてきた地雷をルールとして集積し、保存した瞬間に「ここに罠がある」と教えてくれる、シェルプログラマの相棒として広く支持されている。
この記事の目次
- シェルが抱えてきた落とし穴
- 代表的なルールとSCコード
- 導入とエディタ連携
- 他言語チェッカとの比較と限界
- まとめ
シェルが抱えてきた落とし穴

シェルスクリプトはUNIX文化の根幹を成す道具でありながら、現代的なプログラミング言語と比べると驚くほど落とし穴が多い。代表的なのが「単語分割」で、$varのようにクォートしない変数展開は空白を含む値が来ると意図せず複数の引数に分割され、ファイル名にスペースが含まれているだけでrm -rf的な事故につながりやすい。POSIX shとbashの細かな差、set -eの罠、サブシェルの挙動、cd前の存在チェック忘れなど、業務スクリプトは無数の地雷原を抱えている。
Vidar Holen氏は2012年頃、こうした「人間がいくら気をつけても抜けが出る」シェル特有の問題に対処するため、ShellCheckの開発を開始した。実装言語にHaskellを選んだのは、シェルの複雑な構文解析を厳密に書き下すうえで、強い型システムとパーサコンビネータが向いていたためだと公式FAQで説明されている。GitHub上のkoalaman/shellcheckリポジトリで開発が進められ、現在では300以上のチェックコードが整備されている。
代表的なルールとSCコード

ShellCheckの指摘にはSCxxxxという4桁の番号が振られており、たとえばSC2086は「変数展開がダブルクォートされていない」、SC2046は「コマンド置換の結果がクォートされていない」という意味になる。番号体系のおかげで、エラーをWebで検索すると公式Wikiにある詳細な解説ページに直接たどり着け、なぜ問題か・どう直すべきかが図入りで読める仕組みになっている。この「親切で教育的なドキュメント」が、ShellCheckが他のシェル系ツールと比べて圧倒的な評価を得ている理由のひとつだ。
個別の指摘も実用性が高い。SC2155は「local foo=$(cmd)のように、変数宣言とコマンド実行を一行で書くとcmdの終了コードが失われる」という落とし穴を教えてくれるルールで、これを知らない開発者は驚くほど多い。SC2164は「cd "$dir"の失敗を検査していない」という指摘で、cdに失敗したまま続行することによる予期せぬディレクトリでのrmなど、深刻な事故を未然に防いでくれる。シェル経験10年のベテランでも、ShellCheckにかけると数十件の警告が出る、というのは決して珍しいことではない。
導入とエディタ連携

ShellCheckはバイナリ単体で動くため、apt installやbrew installで導入し、shellcheck script.shと打つだけで使い始められる。Dockerイメージkoalaman/shellcheckも公式に提供されており、CI環境では言語依存を気にせず使えるのが便利だ。VS Codeのshellcheck拡張、JetBrains IDEのShell Support、vimのALEプラグインなど、主要エディタはほぼすべてShellCheckに対応しており、シェルスクリプトを書いた瞬間に警告がインライン表示される体験は、一度味わうと手放せなくなる。
プロジェクト単位の運用としては、リポジトリ直下に.shellcheckrcを置いてプロジェクト全体のオプションを指定するのが標準だ。disable=SC2034のような形で「このプロジェクトでは未使用変数チェックを切る」といった調整ができ、shebangが書かれていないファイルを対象に含めるかどうかも制御できる。GitHub Actionsではludeeus/action-shellcheckのようなアクションが提供されており、PRごとにdiffに対するShellCheck結果をコメントとして付けるワークフローも簡単に組める。
他言語チェッカとの比較と限界

シェルスクリプト向けのツールとしては、ShellCheck以外にmvdan/shでお馴染みのshfmtや、Bash組み込みのbash -nコマンドが存在する。shfmtは整形に特化したツールでgofmtのシェル版とも呼ばれ、解析の深さでは及ばないがフォーマット用途では非常に有用だ。bash -nは構文エラーの有無だけを判定するもので、意味的な落とし穴の検出はできない。対象とする問題の深さが違うため、現場ではShellCheckとshfmtを両方併用するのが一般的だ。
ShellCheckにも限界はあり、対応するのはshとbash、それにdashとkshの一部にとどまる。zshやfishは対象外で、これらを多用するエンジニアは別の解決策を探す必要がある。また外部コマンドを呼び出すケースでは、そのコマンドの戻り値や副作用までは追跡できないため、シェル外の世界の挙動はカバーできない。とはいえ、シェル「内部」で起きる問題に関しては類を見ない網羅性を誇り、運用スクリプトを書く現場ではほぼ必須のツールと言ってよい立ち位置に成長している。
まとめ
ShellCheckは、シェルスクリプトの落とし穴を300以上のルールで指摘してくれるVidar Holen氏発のオープンソース解析ツールである。Haskellで書かれた堅牢なパーサ、SCコードに紐づく丁寧なWiki、主要エディタ・CIへの幅広い連携など、運用スクリプトを書くなら必ず噛ませたい一本となっている。
※本記事はIT用語辞典の手書きドラフトです。公開前に最新情報・出典を確認のうえ加筆修正してください。

コメント