mcpField
S
shellcheck-configuration

shellcheck-configuration

github.com/sickn33测试与质量48.8k177 次安装今天更新
代码仓库

关于 shellcheck-configuration

为 ShellCheck 配置与静态分析提供实践指南,适合维护 Shell 脚本并希望在开发流程中检查常见问题的团队。内容涵盖规则配置、诊断处理、CI 集成及检查结果缓存的注意事项。

主要功能

  1. 01配置目标 Shell 与检查规则
  2. 02解析常见诊断及修复方式
  3. 03设置警告抑制并记录原因
  4. 04集成 CI 与提交前检查
  5. 05说明输出格式与缓存注意事项

适用场景

  1. 01在 CI 中检查 Shell 脚本
  2. 02为项目建立 .shellcheckrc 配置
  3. 03排查并修复 ShellCheck 警告
  4. 04设置提交前的脚本质量检查

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/sickn33/agentic-awesome-skills --skill shellcheck-configuration

安装后在 Claude Code 中输入/shellcheck-configuration确认已加载。

详细介绍

ShellCheck 配置与静态分析

全面介绍如何配置和使用 ShellCheck,以提升 shell 脚本质量、发现常见陷阱,并通过静态代码分析贯彻最佳实践。

以下情况不要使用此技能

  • 任务与 ShellCheck 配置和静态分析无关
  • 需要使用超出此范围的其他领域或工具

说明

  • 明确目标、限制条件和所需输入。
  • 应用相关最佳实践并验证结果。
  • 提供可执行的步骤和验证方法。

以下情况使用此技能

  • 在 CI/CD 流水线中为 shell 脚本设置 lint 检查
  • 分析现有 shell 脚本中的问题
  • 了解 ShellCheck 错误代码和警告
  • 根据特定项目需求配置 ShellCheck
  • 将 ShellCheck 集成到开发工作流中
  • 抑制误报并配置规则集
  • 贯彻一致的代码质量标准
  • 迁移脚本以满足质量门槛

ShellCheck 基础知识

什么是 ShellCheck?

ShellCheck 是一种静态分析工具,可分析 shell 脚本并检测有问题的写法。它支持:

  • Bash、sh、dash、ksh 和其他 POSIX shell
  • 100 多种不同的警告和错误
  • 配置目标 shell 和标志
  • 与编辑器和 CI/CD 系统集成
安装
# 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

配置文件

.shellcheckrc(项目级)

在项目根目录中创建 .shellcheckrc:

# Specify target shell
shell=bash

# Enable optional checks
enable=avoid-nullary-conditions
enable=require-variable-braces

# Disable specific warnings
disable=SC1091
disable=SC2086
选项和诊断参考

使用已安装的 shellcheck --help 和官方诊断页面。不要依赖臆造的 SHELLCHECK_SHELL/STRICT/CONFIG 环境变量,也不要将数字代码范围当作类别。明确设置 --shell=bash(或 sh)、--enable 和排除项;将抑制范围限制在最小范围,并记录原因。

  • SC2086:未加引号的展开可能导致分词和通配符展开。对于 Bash 数组,可使用 for item in "${items[@]}"; do ...; done 进行迭代;给整个标量列表加引号会改变语义,并非通用的修复方法。
  • SC2206:array=( $items ) 仍会执行分词和通配符展开;应有意构造数组,或根据实际格式使用合适的 read/mapfile 操作。
  • SC2181:直接检查命令,例如 if command; then ...; fi。
  • SC2015:当 b 失败时,a && b || c 也会执行 c;如果这会造成影响,请使用 if/else。
  • SC3010:[[ ... ]] 不是 POSIX sh;请使用有效的 [ ... ] 或 case 结构。

请参阅 SC2086 和 官方项目/选项说明。

实用配置示例

最简配置(严格 POSIX)
#!/bin/bash
# Configure for maximum portability

shellcheck \
  --shell=sh \
  --external-sources \
  --check-sourced \
  script.sh
开发配置(采用宽松规则的 Bash)
#!/bin/bash
# Configure for Bash development

shellcheck \
  --shell=bash \
  --exclude=SC1091,SC2119 \
  --enable=all \
  script.sh
CI/CD 集成配置
#!/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
# 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

集成模式

Pre-commit Hook 配置
#!/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 工作流
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" -print0 | xargs -0 shellcheck
GitLab CI 流水线
shellcheck:
  stage: lint
  image: koalaman/shellcheck-alpine
  script:
    - find . -type f -name "*.sh" -print0 | xargs -0 shellcheck
  allow_failure: false

处理 ShellCheck 违规项

抑制特定警告
#!/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
常见违规项及修复方法
SC2086:使用双引号以避免分词
# Problem
for i in $list; do done

# Solution
for i in "${list[@]}"; do printf '%s\n' "$i"; done  # Bash array, not a scalar list
SC2181:直接检查退出代码
# Problem
some_command
if [ $? -eq 0 ]; then
    echo "success"
fi

# Solution
if some_command; then
    echo "success"
fi
SC2015:使用 if-then 替代 && ||
# Problem
[ -f "$file" ] && echo "exists" || echo "not found"

# Solution - clearer intent
if [ -f "$file" ]; then
    echo "exists"
else
    echo "not found"
fi
SC2016:单引号中的表达式不会展开
# Problem
echo 'Variable value: $VAR'

# Solution
echo "Variable value: $VAR"
SC2009:使用 pgrep 替代 grep
# Problem
ps aux | grep -v grep | grep myprocess

# Solution
pgrep -f myprocess

性能优化

检查多个文件
#!/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

缓存结果时,除主脚本外,还应将缓存绑定到 ShellCheck 版本/选项、shell 方言、rc 文件和源文件内容。下面仅使用哈希的示例,在这些输入发生变化时不足以供 CI 重用。Pre-commit 检查必须检查暂存的字节(包括部分暂存的文件),而不是悄悄地 lint 不同的工作树。使用 NUL 分隔的路径,并排除已删除的文件。

缓存结果
#!/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

输出格式

默认格式
shellcheck script.sh

# Output:
# script.sh:1:3: warning: foo is referenced but not assigned. [SC2154]
GCC 格式(用于 CI/CD)
shellcheck --format=gcc script.sh

# Output:
# script.sh:1:3: warning: foo is referenced but not assigned.
JSON 格式(用于解析)
shellcheck --format=json script.sh

# Output:
# [{"file": "script.sh", "line": 1, "column": 3, "level": "warning", "code": 2154, "message": "..."}]
安静格式
shellcheck --format=quiet script.sh

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

最佳实践

  1. 在 CI/CD 中运行 ShellCheck - 在合并前发现问题
  2. 针对目标 Shell 进行配置 - 不要将 bash 按 sh 分析
  3. 记录排除项 - 说明为何抑制违规提示
  4. 处理违规项 - 不要只是禁用警告
  5. 启用严格模式 - 使用 --enable=all,并谨慎设置排除项
  6. 定期更新 - 保持 ShellCheck 为最新版本,以获取新的检查项
  7. 使用 pre-commit hooks - 在推送前于本地发现问题
  8. 集成到编辑器中 - 在开发过程中获取实时反馈

资源

限制

  • 仅当任务明确符合上述范围时,才使用此技能。
  • 不要将输出视为针对特定环境的验证、测试或专家审查的替代品。
  • 如果缺少必要的输入、权限、安全边界或成功标准,请暂停并请求澄清。

评论

支持 Markdown