shellcheck-configuration

精通ShellCheck静态分析配置与使用,提升Shell脚本质量。适用于搭建代码检查基础设施、修复代码问题或确保脚本可移植性场景。

查看详情
name:shellcheck-configurationdescription:Master ShellCheck static analysis configuration and usage for shell script quality. Use when setting up linting infrastructure, fixing code issues, or ensuring script portability.

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.

Do not use this skill when

  • The task is unrelated to shellcheck configuration and static analysis

  • You need a different domain or tool outside this scope
  • Instructions

  • Clarify goals, constraints, and required inputs.

  • Apply relevant best practices and validate outcomes.

  • Provide actionable steps and verification.

  • If detailed examples are required, open resources/implementation-playbook.md.
  • Use this skill when

  • 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

    # 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

    # 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


    # 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

    <div class="overflow-x-auto my-6"><table class="min-w-full divide-y divide-border border border-border"><thead><tr><th class="px-4 py-2 text-left text-sm font-semibold text-foreground bg-muted/50"># SC2009: Consider using pgrep or pidof instead of grep</th><th class="px-4 py-2 text-left text-sm font-semibold text-foreground bg-muted/50">grep</th></tr></thead><tbody class="divide-y divide-border"></tbody></table></div>

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


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

    <div class="overflow-x-auto my-6"><table class="min-w-full divide-y divide-border border border-border"><thead><tr><th class="px-4 py-2 text-left text-sm font-semibold text-foreground bg-muted/50"># SC2015: Avoid using &amp;&amp; and</th><th class="px-4 py-2 text-left text-sm font-semibold text-foreground bg-muted/50">instead of if-then-else</th></tr></thead><tbody class="divide-y divide-border"></tbody></table></div>

    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

    # 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

    # 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)

    #!/bin/bash

    Configure for maximum portability

    shellcheck \
    --shell=sh \
    --external-sources \
    --check-sourced \
    script.sh

    Development Configuration (Bash with Relaxed Rules)

    #!/bin/bash

    Configure for Bash development

    shellcheck \
    --shell=bash \
    --exclude=SC1091,SC2119 \
    --enable=all \
    script.sh

    CI/CD Integration Configuration

    #!/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

    #!/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

    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

    shellcheck:
    stage: lint
    image: koalaman/shellcheck-alpine
    script:
    - find . -type f -name ".sh" -exec shellcheck {} \;
    allow_failure: false

    Handling ShellCheck Violations

    Suppressing Specific Warnings

    #!/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

    # 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

    # Problem
    some_command
    if [ $? -eq 0 ]; then
    echo "success"
    fi

    Solution


    if some_command; then
    echo "success"
    fi

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

    # 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

    # Problem
    echo 'Variable value: $VAR'

    Solution


    echo "Variable value: $VAR"

    SC2009: Use pgrep instead of grep

    # Problem
    ps aux | grep -v grep | grep myprocess

    Solution


    pgrep -f myprocess

    Performance Optimization

    Checking Multiple Files

    #!/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

    #!/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" ]]
    }

    <div class="overflow-x-auto my-6"><table class="min-w-full divide-y divide-border border border-border"><thead><tr><th class="px-4 py-2 text-left text-sm font-semibold text-foreground bg-muted/50">find . -name &quot;.sh&quot;</th><th class="px-4 py-2 text-left text-sm font-semibold text-foreground bg-muted/50">while read -r script; do</th></tr></thead><tbody class="divide-y divide-border"></tbody></table></div>
    done

    Output Formats

    Default Format

    shellcheck script.sh

    Output:


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

    GCC Format (for CI/CD)

    shellcheck --format=gcc script.sh

    Output:


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

    JSON Format (for parsing)

    shellcheck --format=json script.sh

    Output:


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

    Quiet Format

    shellcheck --format=quiet script.sh

    Returns non-zero if issues found, no output otherwise

    Best Practices

  • Run ShellCheck in CI/CD - Catch issues before merging

  • Configure for your target shell - Don't analyze bash as sh

  • Document exclusions - Explain why violations are suppressed

  • Address violations - Don't just disable warnings

  • Enable strict mode - Use --enable=all` with careful exclusions

  • Update regularly - Keep ShellCheck current for new checks

  • Use pre-commit hooks - Catch issues locally before pushing

  • 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/

    1. shellcheck-configuration - Agent Skills