---
id: sm-shellcheck-configuration
name: "shellcheck-configuration"
url: https://skills.yangsir.net/skill/sm-shellcheck-configuration
author: wshobson
domain: ai-agent-orchestration-collaboration
tags: ["shellcheck", "shell-scripting", "static-analysis", "devops", "bash/zsh"]
install_count: 6600
rating: 4.50 (50 reviews)
github: https://github.com/wshobson/agents
---

# shellcheck-configuration

> 熟悉ShellCheck配置，结合智能自动化和多智能体编排，提升Shell脚本的质量与安全性，减少潜在错误。

**Stats**: 6,600 installs · 4.5/5 (50 reviews)

## Before / After 对比

### ShellCheck配置优化，提升脚本质量与安全性

## Readme

# shellcheck-configuration

# 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

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

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

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

find . -name "*.sh" | while read -r script; do
    check_script "$script" || exit 1
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

Weekly Installs3.0KRepository[wshobson/agents](https://github.com/wshobson/agents)GitHub Stars31.5KFirst SeenJan 20, 2026Security Audits[Gen Agent Trust HubPass](/wshobson/agents/shellcheck-configuration/security/agent-trust-hub)[SocketPass](/wshobson/agents/shellcheck-configuration/security/socket)[SnykPass](/wshobson/agents/shellcheck-configuration/security/snyk)Installed onclaude-code2.3Kopencode2.2Kgemini-cli2.2Kcodex2.1Kcursor2.1Kgithub-copilot1.8K

---
*Source: https://skills.yangsir.net/skill/sm-shellcheck-configuration*
*Markdown mirror: https://skills.yangsir.net/api/skill/sm-shellcheck-configuration/markdown*