🎯

shellcheck-configuration

🎯Skill

from ovachiever/droid-tings

VibeIndex|
What it does

Configures and applies ShellCheck for robust shell script static analysis and quality enforcement.

πŸ“¦

Part of

ovachiever/droid-tings(370 items)

shellcheck-configuration

Installation

git cloneClone repository
git clone https://github.com/koalaman/shellcheck.git
MakeRun with Make
make build
MakeRun with Make
make install
πŸ“– Extracted from docs: ovachiever/droid-tings
14Installs
20
-
AddedFeb 4, 2026

Skill Details

SKILL.md

Master ShellCheck static analysis configuration and usage for shell script quality. Use when setting up linting infrastructure, fixing code issues, or ensuring script portability.

Overview

# ShellCheck Configuration and Static Analysis

Comprehensive guidance for configuring and using ShellCheck to improve shell script quality, catch common pitfalls, and enforce best practices through static code analysis.

When to Use This Skill

  • Setting up linting for shell scripts in CI/CD pipelines
  • Analyzing existing shell scripts for issues
  • Understanding ShellCheck error codes and warnings
  • Configuring ShellCheck for specific project requirements
  • Integrating ShellCheck into development workflows
  • Suppressing false positives and configuring rule sets
  • Enforcing consistent code quality standards
  • Migrating scripts to meet quality gates

ShellCheck Fundamentals

What is ShellCheck?

ShellCheck is a static analysis tool that analyzes shell scripts and detects problematic patterns. It supports:

  • Bash, sh, dash, ksh, and other POSIX shells
  • Over 100 different warnings and errors
  • Configuration for target shell and flags
  • Integration with editors and CI/CD systems

Installation

```bash

# macOS with Homebrew

brew install shellcheck

# Ubuntu/Debian

apt-get install shellcheck

# From source

git clone https://github.com/koalaman/shellcheck.git

cd shellcheck

make build

make install

# Verify installation

shellcheck --version

```

Configuration Files

.shellcheckrc (Project Level)

Create .shellcheckrc in your project root:

```

# Specify target shell

shell=bash

# Enable optional checks

enable=avoid-nullary-conditions

enable=require-variable-braces

# Disable specific warnings

disable=SC1091

disable=SC2086

```

Environment Variables

```bash

# Set default shell target

export SHELLCHECK_SHELL=bash

# Enable strict mode

export SHELLCHECK_STRICT=true

# Specify configuration file location

export SHELLCHECK_CONFIG=~/.shellcheckrc

```

Common ShellCheck Error Codes

SC1000-1099: Parser Errors

```bash

# SC1004: Backslash continuation not followed by newline

echo hello\

world # Error - needs line continuation

# SC1008: Invalid data for operator `=='

if [[ $var = "value" ]]; then # Space before ==

true

fi

```

SC2000-2099: Shell Issues

```bash

# SC2009: Consider using pgrep or pidof instead of grep|grep

ps aux | grep -v grep | grep myprocess # Use pgrep instead

# SC2012: Use ls only for viewing. Use find for reliable output

for file in $(ls -la) # Better: use find or globbing

# SC2015: Avoid using && and || instead of if-then-else

[[ -f "$file" ]] && echo "found" || echo "not found" # Less clear

# SC2016: Expressions don't expand in single quotes

echo '$VAR' # Literal $VAR, not variable expansion

# SC2026: This word is non-standard. Set POSIXLY_CORRECT

# when using with scripts for other shells

```

SC2100-2199: Quoting Issues

```bash

# SC2086: Double quote to prevent globbing and word splitting

for i in $list; do # Should be: for i in $list or for i in "$list"

echo "$i"

done

# SC2115: Literal tilde in path not expanded. Use $HOME instead

~/.bashrc # In strings, use "$HOME/.bashrc"

# SC2181: Check exit code directly with if, not indirectly in a list

some_command

if [ $? -eq 0 ]; then # Better: if some_command; then

# SC2206: Quote to prevent word splitting or set IFS

array=( $items ) # Should use: array=( $items )

```

SC3000-3999: POSIX Compliance Issues

```bash

# SC3010: In POSIX sh, use 'case' instead of 'cond && foo'

[[ $var == "value" ]] && do_something # Not POSIX

# SC3043: In POSIX sh, use 'local' is undefined

function my_func() {

local var=value # Not POSIX in some shells

}

```

Practical Configuration Examples

Minimal Configuration (Strict POSIX)

```bash

#!/bin/bash

# Configure for maximum portability

shellcheck \

--shell=sh \

--external-sources \

--check-sourced \

script.sh

```

Development Configuration (Bash with Relaxed Rules)

```bash

#!/bin/bash

# Configure for Bash development

shellcheck \

--shell=bash \

--exclude=SC1091,SC2119 \

--enable=all \

script.sh

```

CI/CD Integration Configuration

```bash

#!/bin/bash

set -Eeuo pipefail

# Analyze all shell scripts and fail on issues

find . -type f -name "*.sh" | while read -r script; do

echo "Checking: $script"

shellcheck \

--shell=bash \

--format=gcc \

--exclude=SC1091 \

"$script" || exit 1

done

```

.shellcheckrc for Project

```

# Shell dialect to analyze against

shell=bash

# Enable optional checks

enable=avoid-nullary-conditions,require-variable-braces,check-unassigned-uppercase

# Disable specific warnings

# SC1091: Not following sourced files (many false positives)

disable=SC1091

# SC2119: Use function_name instead of function_name -- (arguments)

disable=SC2119

# External files to source for context

external-sources=true

```

Integration Patterns

Pre-commit Hook Configuration

```bash

#!/bin/bash

# .git/hooks/pre-commit

#!/bin/bash

set -e

# Find all shell scripts changed in this commit

git diff --cached --name-only | grep '\.sh$' | while read -r script; do

echo "Linting: $script"

if ! shellcheck "$script"; then

echo "ShellCheck failed on $script"

exit 1

fi

done

```

GitHub Actions Workflow

```yaml

name: ShellCheck

on: [push, pull_request]

jobs:

shellcheck:

runs-on: ubuntu-latest

steps:

- uses: actions/checkout@v3

- name: Run ShellCheck

run: |

sudo apt-get install shellcheck

find . -type f -name "*.sh" -exec shellcheck {} \;

```

GitLab CI Pipeline

```yaml

shellcheck:

stage: lint

image: koalaman/shellcheck-alpine

script:

- find . -type f -name "*.sh" -exec shellcheck {} \;

allow_failure: false

```

Handling ShellCheck Violations

Suppressing Specific Warnings

```bash

#!/bin/bash

# Disable warning for entire line

# shellcheck disable=SC2086

for file in $(ls -la); do

echo "$file"

done

# Disable for entire script

# shellcheck disable=SC1091,SC2119

# Disable multiple warnings (format varies)

command_that_fails() {

# shellcheck disable=SC2015

[ -f "$1" ] && echo "found" || echo "not found"

}

# Disable specific check for source directive

# shellcheck source=./helper.sh

source helper.sh

```

Common Violations and Fixes

#### SC2086: Double quote to prevent word splitting

```bash

# Problem

for i in $list; do done

# Solution

for i in $list; do done # If $list is already quoted, or

for i in "${list[@]}"; do done # If list is an array

```

#### SC2181: Check exit code directly

```bash

# Problem

some_command

if [ $? -eq 0 ]; then

echo "success"

fi

# Solution

if some_command; then

echo "success"

fi

```

#### SC2015: Use if-then instead of && ||

```bash

# Problem

[ -f "$file" ] && echo "exists" || echo "not found"

# Solution - clearer intent

if [ -f "$file" ]; then

echo "exists"

else

echo "not found"

fi

```

#### SC2016: Expressions don't expand in single quotes

```bash

# Problem

echo 'Variable value: $VAR'

# Solution

echo "Variable value: $VAR"

```

#### SC2009: Use pgrep instead of grep

```bash

# Problem

ps aux | grep -v grep | grep myprocess

# Solution

pgrep -f myprocess

```

Performance Optimization

Checking Multiple Files

```bash

#!/bin/bash

# Sequential checking

for script in *.sh; do

shellcheck "$script"

done

# Parallel checking (faster)

find . -name "*.sh" -print0 | \

xargs -0 -P 4 -n 1 shellcheck

```

Caching Results

```bash

#!/bin/bash

CACHE_DIR=".shellcheck_cache"

mkdir -p "$CACHE_DIR"

check_script() {

local script="$1"

local hash

local cache_file

hash=$(sha256sum "$script" | cut -d' ' -f1)

cache_file="$CACHE_DIR/$hash"

if [[ ! -f "$cache_file" ]]; then

if shellcheck "$script" > "$cache_file" 2>&1; then

touch "$cache_file.ok"

else

return 1

fi

fi

[[ -f "$cache_file.ok" ]]

}

find . -name "*.sh" | while read -r script; do

check_script "$script" || exit 1

done

```

Output Formats

Default Format

```bash

shellcheck script.sh

# Output:

# script.sh:1:3: warning: foo is referenced but not assigned. [SC2154]

```

GCC Format (for CI/CD)

```bash

shellcheck --format=gcc script.sh

# Output:

# script.sh:1:3: warning: foo is referenced but not assigned.

```

JSON Format (for parsing)

```bash

shellcheck --format=json script.sh

# Output:

# [{"file": "script.sh", "line": 1, "column": 3, "level": "warning", "code": 2154, "message": "..."}]

```

Quiet Format

```bash

shellcheck --format=quiet script.sh

# Returns non-zero if issues found, no output otherwise

```

Best Practices

  1. Run ShellCheck in CI/CD - Catch issues before merging
  2. Configure for your target shell - Don't analyze bash as sh
  3. Document exclusions - Explain why violations are suppressed
  4. Address violations - Don't just disable warnings
  5. Enable strict mode - Use --enable=all with careful exclusions
  6. Update regularly - Keep ShellCheck current for new checks
  7. Use pre-commit hooks - Catch issues locally before pushing
  8. Integrate with editors - Get real-time feedback during development

Resources

  • ShellCheck GitHub: https://github.com/koalaman/shellcheck
  • ShellCheck Wiki: https://www.shellcheck.net/wiki/
  • Error Code Reference: https://www.shellcheck.net/