关于 shellcheck-configuration
为 ShellCheck 配置与静态分析提供实践指南,适合维护 Shell 脚本并希望在开发流程中检查常见问题的团队。内容涵盖规则配置、诊断处理、CI 集成及检查结果缓存的注意事项。
主要功能
- 01配置目标 Shell 与检查规则
- 02解析常见诊断及修复方式
- 03设置警告抑制并记录原因
- 04集成 CI 与提交前检查
- 05说明输出格式与缓存注意事项
适用场景
- 01在 CI 中检查 Shell 脚本
- 02为项目建立 .shellcheckrc 配置
- 03排查并修复 ShellCheck 警告
- 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 结构。
实用配置示例
最简配置(严格 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
最佳实践
- 在 CI/CD 中运行 ShellCheck - 在合并前发现问题
- 针对目标 Shell 进行配置 - 不要将 bash 按 sh 分析
- 记录排除项 - 说明为何抑制违规提示
- 处理违规项 - 不要只是禁用警告
- 启用严格模式 - 使用
--enable=all,并谨慎设置排除项 - 定期更新 - 保持 ShellCheck 为最新版本,以获取新的检查项
- 使用 pre-commit hooks - 在推送前于本地发现问题
- 集成到编辑器中 - 在开发过程中获取实时反馈
资源
- ShellCheck GitHub:https://github.com/koalaman/shellcheck
- ShellCheck Wiki:https://www.shellcheck.net/wiki/
- 错误代码参考:https://www.shellcheck.net/
限制
- 仅当任务明确符合上述范围时,才使用此技能。
- 不要将输出视为针对特定环境的验证、测试或专家审查的替代品。
- 如果缺少必要的输入、权限、安全边界或成功标准,请暂停并请求澄清。
评论
支持 Markdown