ShellCheck について
ShellCheck はシェルスクリプトを分析して、一般的なエラー、移植性の問題、コードの問題を特定します。複数のスクリプトをチェックでき、具体的な診断と改善提案を提供します。
主な機能
- 01シェルスクリプトの構文エラーとロジックの問題を検出
- 02クロスプラットフォーム互換性の問題を特定
- 03複数のスクリプトファイルをバッチ分析
活用シーン
- 01CI/CD パイプラインでシェルスクリプト品質を自動検証する
- 02複雑なシェルスクリプトの問題をデバッグする
- 03インフラストラクチャ自動化スクリプトの信頼性を向上させる
インストール
OS またはパッケージマネージャーを選び、コマンドをターミナルで実行します。
インストール後にshellcheck --versionを実行して確認します。
コマンド例
よく使うコマンドを使う順に並べています。
詳細
ShellCheck - シェルスクリプトの静的解析ツール
ShellCheck は、bash/sh シェルスクリプトに対する警告や提案を行う GPLv3 のツールです:

ShellCheck の目標は次のとおりです
-
シェルが不可解なエラーメッセージを返す原因となる、初心者によくある構文の問題を指摘し、明確にすること。
-
シェルが奇妙で直感に反する動作をする原因となる、中級者によくある意味論的な問題を指摘し、明確にすること。
-
他の環境では動作していた上級ユーザーのスクリプトが、将来の状況で失敗する原因となりうる、微妙な注意点、コーナーケース、落とし穴を指摘すること。
ShellCheck が特定するのに役立つ例については、悪いコードのギャラリーをご覧ください!
目次
使い方
ShellCheck を使う方法はいくつかあります!
ウェブ上で
https://www.shellcheck.net にシェルスクリプトを貼り付けると、すぐにフィードバックが得られます。
ShellCheck.net は常に最新の git コミットに同期されており、ShellCheck を試す最も簡単な方法です。友達にも教えてあげましょう!
ターミナルから
ターミナルで shellcheck yourscript を実行すると、上記のように即座に出力が得られます。
エディタで
さまざまなエディタで ShellCheck の提案を直接確認できます。
。
。
-
Sublime では、SublimeLinter を通じて。
-
Pulsar Edit (旧 Atom) では、linter-shellcheck-pulsar を通じて。
-
VSCode では、vscode-shellcheck を通じて。
-
その他のほとんどのエディタでは、GCC エラー互換を通じて。
ビルドまたはテストスイートでの使用
ShellCheck は主に対話的な使用を想定していますが、ビルドやテストスイートに簡単に追加できます。
終了コードを標準的に使用するため、プロセスの一部として shellcheck コマンドを追加するだけで済みます。
たとえば、Makefile では次のようになります。
check-scripts:
# Fail if any of these files have warnings
shellcheck myscripts/*.sh
または、Travis CI の .travis.yml ファイルでは次のようになります。
script:
# Fail if any of these files have warnings
- shellcheck myscripts/*.sh
ShellCheck がプリインストールされ、すぐに使用できるサービスとプラットフォーム:
- Travis CI
- Codacy
- Code Climate
- Code Factor
- Codety(Codety Scanner 経由)
- CircleCI(ShellCheck Orb 経由)
- Github(Linux のみ)
- Trunk Code Quality(汎用リンター。shellcheck インストールのバージョンを明示的に指定できます)(shellcheck プラグイン 経由)
- CodeRabbit
GitLab をはじめとするほとんどの他のサービスでは、 システムのパッケージマネージャー(インストールを参照)を通じて、 またはバイナリリリースをダウンロードして展開することで、 ShellCheck を自分でインストールできます。
いずれにしても、特定の ShellCheck バージョンを手動でインストールすることをおすすめします。これにより、 新しい警告を含む新しいバージョンが公開されたときの予期しないビルドの失敗を避けられます。
カスタマイズしたフィルタリングやレポートのために、ShellCheck はシンプルな JSON、CheckStyle 互換の XML、 GCC 互換の警告、および人間が読めるテキスト(ANSI カラーの有無を問わず)を出力できます。詳細については、 Integration wiki ページを参照してください。
インストール
ShellCheck をローカルにインストールする最も簡単な方法は、パッケージマネージャーを使うことです。
Cabal を使用するシステムの場合(~/.cabal/bin にインストールされます):
cabal update
cabal install ShellCheck
Stack を使用するシステムの場合(~/.local/bin にインストールされます):
stack update
stack install ShellCheck
Debian ベースのディストリビューションの場合:
sudo apt install shellcheck
Arch Linux ベースのディストリビューションの場合:
pacman -S shellcheck
または、AUR から依存関係のない shellcheck-bin を入手してください。
Gentoo ベースのディストリビューションの場合:
emerge --ask shellcheck
EPEL ベースのディストリビューションの場合:
sudo yum -y install epel-release
sudo yum install ShellCheck
Fedora ベースのディストリビューションの場合:
dnf install ShellCheck
FreeBSD の場合:
pkg install hs-ShellCheck
Homebrew を使用する macOS(OS X)の場合:
brew install shellcheck
または MacPorts の場合:
sudo port install shellcheck
OpenBSD の場合:
pkg_add shellcheck
openSUSE の場合
zypper in ShellCheck
または OneClickInstall を使用してください - https://software.opensuse.org/package/ShellCheck
Solus の場合:
eopkg install shellcheck
Windows の場合(chocolatey 経由):
C:\> choco install shellcheck
または Windows の場合(winget 経由):
C:\> winget install --id koalaman.shellcheck
または Windows の場合(scoop 経由):
C:\> scoop install shellcheck
conda-forge から:
conda install -c conda-forge shellcheck
Snap Store から:
snap install --channel=edge shellcheck
Docker Hub から:
docker run --rm -v "$PWD:/mnt" koalaman/shellcheck:stable myscript
# Or :v0.4.7 for that version, or :latest for daily builds
または、拡張用により大きな Alpine Linux ベースのイメージが必要な場合は、koalaman/shellcheck-alpine を使用してください。通常の Alpine イメージとまったく同じように動作しますが、shellcheck があらかじめインストールされています。
mise を使用する場合:
mise use shellcheck
nix パッケージマネージャー を使用する場合:
nix-env -iA nixpkgs.shellcheck
Flox パッケージマネージャー を使用する場合
flox install shellcheck
または、最新リリースのコンパイル済みバイナリをこちらからダウンロードできます:
- Linux, x86_64(静的リンク)
- Linux, armv6hf、Raspberry Pi など(静的リンク)
- Linux, aarch64、ARM64 とも呼ばれます(静的リンク)
- Linux, riscv64(静的リンク)
- macOS, aarch64
- macOS, x86_64
- Windows, x86
その他のリリースについては、GitHub Releases を参照してください (毎日の git ビルドを含む 最新 のメタリリースもあります)。
ディストリビューションのパッケージには、すでに man ページが含まれています。ソースからビルドする場合は、次のコマンドでインストールできます:
pandoc -s -f markdown-smart -t man shellcheck.1.md -o shellcheck.1
sudo mv shellcheck.1 /usr/share/man/man1
pre-commit
pre-commit 経由で ShellCheck を実行するには、.pre-commit-config.yaml にフックを追加します:
repos:
- repo: https://github.com/koalaman/shellcheck-precommit
rev: v0.11.0
hooks:
- id: shellcheck
# args: ["--severity=warning"] # Optionally only show errors and warnings
Travis CI
Travis CI では ShellCheck がデフォルトで統合されているため、手動でインストールする必要はありません。
それでも、都合のよいタイミングでアップグレードしたり、最新リリースを使用していることを確認したりするためにインストールしたい場合は、 以下の手順に従ってバイナリ版をインストールしてください。
コンパイル済みバイナリのインストール
コンパイル済みバイナリは tar.xz ファイルで提供されます。展開するには、
xz がインストールされていることを確認してください。
Debian/Ubuntu/Mint では、apt install xz-utils を実行できます。
Redhat/Fedora/CentOS では、yum -y install xz を実行してください。
簡単なインストーラーでは、次のように実行できます:
scversion="stable" # or "v0.4.7", or "latest"
wget -qO- "https://github.com/koalaman/shellcheck/releases/download/${scversion?}/shellcheck-${scversion?}.linux.x86_64.tar.xz" | tar -xJv
cp "shellcheck-${scversion}/shellcheck" /usr/bin/
shellcheck --version
ソースからのコンパイル
このセクションでは、ソースディレクトリから ShellCheck をビルドする方法を説明します。ShellCheck は Haskell で書かれており、コンパイルには 2GB の RAM が必要です。
Cabal のインストール
ShellCheck は Cabal を使ってビルドおよびパッケージ化されています。システムのパッケージマネージャー(apt-get、brew、emerge、yum、zypper など)から cabal-install パッケージをインストールしてください。
macOS(OS X)では、brew を使うと Cabal をすばやくインストールできます。ソースからコンパイルすると 30 分以上かかるところ、数分で完了します。
$ brew install cabal-install
MacPorts では、パッケージ名は hs-cabal-install です。一方、ネイティブ Windows のユーザーは、https://www.haskell.org/platform/ から Haskell platform の最新バージョンをインストールしてください。
cabal がインストールされていることを確認し、依存関係の一覧を更新します。
$ cabal update
ShellCheck のコンパイル
このリポジトリを git clone し、ShellCheck のソースディレクトリに cd して、ビルド/インストールします。
$ cabal install
これにより ShellCheck がコンパイルされ、~/.cabal/bin ディレクトリにインストールされます。
このディレクトリを PATH に追加してください(bash の場合は、~/.bashrc に以下を追加します)。
export PATH="$HOME/.cabal/bin:$PATH"
ログアウトして再度ログインし、PATH が正しく設定されていることを確認してください。
$ which shellcheck
~/.cabal/bin/shellcheck
ネイティブ Windows では、PATH はすでに設定されているはずですが、システムでレガシーなコードページが使用されている場合があります。cmd.exe、powershell.exe、Powershell ISE では、ラスターフォントではなく TrueType フォントを使い、chcp でアクティブなコードページを UTF-8(65001)に設定してください。
chcp 65001
Powershell ISE では、さらに出力エンコーディングを更新する必要がある場合があります。
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
テストの実行
ユニットテストスイートを実行するには、次のようにします。
$ cabal test
問題のあるコードのギャラリー
ShellCheck はどのような問題を検出するのでしょうか?検出される問題の不完全な一覧を以下に示します。
引用符の使用
ShellCheck は、誤った引用符の使用をいくつかの種類に分けて認識できます。
echo $1 # Unquoted variables
find . -name *.ogg # Unquoted find/grep patterns
rm "~/my file.txt" # Quoted tilde expansion
v='--verbose="true"'; cmd $v # Literal quotes in variables
for f in "*.ogg" # Incorrectly quoted 'for' loops
touch $@ # Unquoted $@
echo 'Don't forget to restart!' # Singlequote closed by apostrophe
echo 'Don\'t try this at home' # Attempting to escape ' in ''
echo 'Path is $PATH' # Variables in single quotes
trap "echo Took ${SECONDS}s" 0 # Prematurely expanded trap
unset var[i] # Array index treated as glob
条件式
ShellCheck は、誤ったテスト文の多くの種類を認識できます。
[[ n != 0 ]] # Constant test expressions
[[ -e *.mpg ]] # Existence checks of globs
[[ $foo==0 ]] # Always true due to missing spaces
[[ -n "$foo " ]] # Always true due to literals
[[ $foo =~ "fo+" ]] # Quoted regex in =~
[ foo =~ re ] # Unsupported [ ] operators
[ $1 -eq "shellcheck" ] # Numerical comparison of strings
[ $n && $m ] # && in [ .. ]
[ grep -q foo file ] # Command without $(..)
[[ "$$file" == *.jpg ]] # Comparisons that can't succeed
(( 1 -lt 2 )) # Using test operators in ((..))
[ x ] & [ y ] | [ z ] # Accidental backgrounding and piping
誤用されやすいコマンド
ShellCheck は、コマンドが誤って使用されているケースを認識できます。
grep '*foo*' file # Globs in regex contexts
find . -exec foo {} && bar {} \; # Prematurely terminated find -exec
sudo echo 'Var=42' > /etc/profile # Redirecting sudo
time --format=%s sleep 10 # Passing time(1) flags to time builtin
while read h; do ssh "$h" uptime # Commands eating while loop input
alias archive='mv $1 /backup' # Defining aliases with arguments
tr -cd '[a-zA-Z0-9]' # [] around ranges in tr
exec foo; echo "Done!" # Misused 'exec'
find -name \*.bak -o -name \*~ -delete # Implicit precedence in find
# find . -exec foo > bar \; # Redirections in find
f() { whoami; }; sudo f # External use of internal functions
初心者によくある間違い
ShellCheck は、初心者によくある構文エラーを多数認識します。
var = 42 # Spaces around = in assignments
$foo=42 # $ in assignments
for $var in *; do ... # $ in for loop variables
var$n="Hello" # Wrong indirect assignment
echo ${var$n} # Wrong indirect reference
var=(1, 2, 3) # Comma separated arrays
array=( [index] = value ) # Incorrect index initialization
echo $var[14] # Missing {} in array references
echo "Argument 10 is $10" # Positional parameter misreference
if $(myfunction); then ..; fi # Wrapping commands in $()
else if othercondition; then .. # Using 'else if'
f; f() { echo "hello world; } # Using function before definition
[ false ] # 'false' being true
if ( -f file ) # Using (..) instead of test
スタイル
ShellCheck は、スタイルを改善するための提案を行えます。
[[ -z $(find /tmp | grep mpg) ]] # Use grep -q instead
a >> log; b >> log; c >> log # Use a redirection block instead
echo "The time is `date`" # Use $() instead
cd dir; process *; cd ..; # Use subshells instead
echo $[1+2] # Use standard $((..)) instead of old $[]
echo $(($RANDOM % 6)) # Don't use $ on variables in $((..))
echo "$(date)" # Useless use of echo
cat file | grep foo # Useless use of cat
データと型のエラー
ShellCheck は、データや型に関する問題を認識できます。
args="$@" # Assigning arrays to strings
files=(foo bar); echo "$files" # Referencing arrays as strings
declare -A arr=(foo bar) # Associative arrays without index
printf "%s\n" "Arguments: $@." # Concatenating strings and arrays
[[ $# > 2 ]] # Comparing numbers as strings
var=World; echo "Hello " var # Unused lowercase variables
echo "Hello $name" # Unassigned lowercase variables
cmd | read bar; echo $bar # Assignments in subshells
cat foo | cp bar # Piping to commands that don't read
printf '%s: %s\n' foo # Mismatches in printf argument count
eval "${array[@]}" # Lost word boundaries in array eval
for i in "${x[@]}"; do ${x[$i]} # Using array value as key
堅牢性
ShellCheck は、スクリプトの堅牢性を高めるための提案を行えます。
rm -rf "$STEAMROOT/"* # Catastrophic rm
touch ./-l; ls * # Globs that could become options
find . -exec sh -c 'a && b {}' \; # Find -exec shell injection
printf "Hello $name" # Variables in printf format
for f in $(ls *.txt); do # Iterating over ls output
export MYVAR=$(cmd) # Masked exit codes
case $version in 2.*) :;; 2.6.*) # Shadowed case branches
移植性
shebang でサポートされていない機能を使うと、ShellCheck は警告します。たとえば、shebang を #!/bin/sh に設定すると、ShellCheck は checkbashisms と同様の移植性に関する問題を警告します。
echo {1..$n} # Works in ksh, but not bash/dash/sh
echo {1..10} # Works in ksh and bash, but not dash/sh
echo -n 42 # Works in ksh, bash and dash, undefined in sh
expr match str regex # Unportable alias for `expr str : regex`
trap 'exit 42' sigint # Unportable signal spec
cmd &> file # Unportable redirection operator
read foo < /dev/tcp/host/22 # Unportable intercepted files
foo-bar() { ..; } # Undefined/unsupported function name
[ $UID = 0 ] # Variable undefined in dash/sh
local var=value # local is undefined in sh
time sleep 1 | sleep 5 # Undefined uses of 'time'
その他
ShellCheck は、ほかにもさまざまな問題を認識します。
PS1='\e[0;32m\$\e[0m ' # PS1 colors not in \[..\]
PATH="$PATH:~/bin" # Literal tilde in $PATH
rm “file” # Unicode quotes
echo "Hello world" # Carriage return / DOS line endings
echo hello \ # Trailing spaces after \
var=42 echo $var # Expansion of inlined environment
!# bin/bash -x -e # Common shebang errors
echo $((n/180*100)) # Unnecessary loss of precision
ls *[:digit:].txt # Bad character class globs
sed 's/foo/bar/' file > file # Redirecting to input
var2=$var2 # Variable assigned to itself
[ x$var = xval ] # Antiquated x-comparisons
ls() { ls -l "$@"; } # Infinitely recursive wrapper
alias ls='ls -l'; ls foo # Alias used before it takes effect
for x; do for x; do # Nested loop uses same variable
while getopts "a" f; do case $f in "b") # Unhandled getopts flags
利用者の声
最初は「shellcheck は最高だ」と思うけれど、やがて「なんでまだ bash を使っているんだ」と思うようになる
Alexander Tarasikov, Twitter より
問題の無視
環境変数、コマンドライン、個別指定、またはファイル内での一括指定によって、問題を無視できます。
https://github.com/koalaman/shellcheck/wiki/Ignore
バグの報告
バグや機能の提案は、GitHub の issue トラッカーから報告してください。
https://github.com/koalaman/shellcheck/issues
貢献
コードやドキュメントへのパッチは、GitHub のプルリクエストとしてお送りください。DevGuide を確認してください。 ShellCheck Wiki に掲載されています。
貢献内容は GNU GPLv3 の下でライセンスされる必要があります。 著作権は貢献者が保持します。
著作権
ShellCheck は GNU General Public License, v3 の下でライセンスされています。このライセンスのコピーは LICENSE ファイルに含まれています。
著作権 2012-2019、Vidar 'koala_man' Holen および貢献者。
ShellCheck をお楽しみください!