Back to DevOps & CI/CD

shellcheck-configuration

shellcheckstatic analysisshell scriptingbashlintingcode qualitydevopsci/cd
36.8k📄 MIT🕒 2026-06-16Source ↗

Install this skill

npx skills add wshobson/agents

Works across Claude Code, Cursor, Codex, Copilot & Antigravity

ShellCheck configuration provides a standardized method for integrating static analysis into shell development workflows. It acts as a linting framework for POSIX, Bash, dash, and ksh scripts by identifying common syntax errors, security vulnerabilities, and portability issues before execution. By maintaining a centralized .shellcheckrc file at the project root, developers ensure consistent enforcement of coding standards across teams. The tool maps issues to specific error codes, such as SC2086 for quote management or SC3000-series for POSIX compatibility, allowing for granular suppression or enabling of checks. Proper configuration enables CI/CD pipelines to fail builds when scripts violate defined quality gates, effectively preventing runtime failures caused by globbing mistakes, word splitting, or non-portable syntax. This skill covers setting target dialects, managing external source files, and automating linting tasks through Git hooks or CI runners.

When to Use This Skill

  • Standardizing coding style across shell scripts in a DevOps repository
  • Validating scripts for cross-platform portability before deployment
  • Enforcing strict quoting and variable expansion rules in production scripts
  • Preventing common logic bugs like incorrect exit code checks or pipe failures

How to Invoke This Skill

Example prompts that trigger this skill in Claude Code, Cursor, or Antigravity:

  • Lint my shell scripts
  • Set up shellcheck for my bash project
  • How to ignore shellcheck warnings
  • Configure shellcheck in my repository
  • Fix my shell script errors
  • Ensure bash script portability

Pro Tips

  • 💡Always integrate ShellCheck into your pre-commit hooks or CI/CD pipelines to catch issues early and maintain a clean codebase.
  • 💡When suppressing warnings with `SC2xxx`, add a brief comment explaining *why* the suppression is necessary for future maintainability.
  • 💡Utilize ShellCheck's `--shell` option to accurately target your script's intended interpreter (e.g., `bash`, `sh`) to avoid false positives or missed warnings.

What this skill does

  • Defines persistent linting rules via .shellcheckrc configuration files
  • Maps complex shell behaviors to actionable error codes for debugging
  • Enforces POSIX compliance across varying shell environments
  • Automates linting passes within CI/CD pipelines and Git pre-commit hooks
  • Supports fine-grained suppression of specific warnings or false positives

When not to use it

  • Analyzing binaries or compiled languages that are not shell scripts
  • Complex shell scripts that rely on highly dynamic, runtime-only generated syntax

Example workflow

  1. Install the shellcheck utility via system package manager
  2. Initialize a .shellcheckrc file in the repository root directory
  3. Define shell dialect and required checks inside the configuration file
  4. Implement a loop in CI to iterate through and validate all .sh files
  5. Configure pre-commit hooks to run shellcheck only on modified files
  6. Review output logs and address flagged error codes

Prerequisites

  • Basic knowledge of shell scripting
  • Access to terminal for CLI execution
  • Existing directory structure for shell scripts

Pitfalls & limitations

  • !False positives often arise from sourced files that ShellCheck cannot resolve automatically
  • !Ignoring warnings like SC1091 can hide genuine issues with missing dependencies
  • !Strict POSIX mode may reject valid Bash-specific features if misconfigured

FAQ

How do I ignore specific errors?
Add the error code to the disable directive in your .shellcheckrc file or use a directive comment like # shellcheck disable=SC2086 inside the script itself.
Can I use it for scripts other than Bash?
Yes, you can specify the target shell dialect using the --shell flag or the shell= option in your configuration file.
Why does it complain about sourced files?
ShellCheck often cannot locate sourced files automatically; use the external-sources=true directive to allow it to follow relative paths.

How it compares

Unlike manual review, ShellCheck programmatically identifies thousands of edge-case syntax bugs that even experienced developers overlook, while its configuration file ensures uniform standards across team contributions.

Source & trust

37k stars📄 MIT🕒 Updated 2026-06-16
📄 Full skill instructions — original source: wshobson/agents
# 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

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/

How to Use This Skill Unit

Option A: Project-Specific (Recommended)

  1. Click "Download" above
  2. In your project, create the directory: .agent/skills/shellcheck-configuration/
  3. Save the file as SKILL.md
  4. The agent will automatically discover the skill based on its description.

Option B: Global Installation (All Agents)

Save the file to these locations to make it available across all projects:

  • Claude Code: ~/.claude/skills/wshobson/agents/shellcheck-configuration/SKILL.md
  • Cursor: ~/.cursor/skills/wshobson/agents/shellcheck-configuration/SKILL.md
  • Antigravity: ~/.gemini/antigravity/skills/wshobson/agents/shellcheck-configuration/SKILL.md

🚀 Install with CLI:
npx skills add wshobson/agents

Read the Master Guide: Mastering Agent Skills

Recommended Rules

View more rules

Recommended Workflows

View more workflows

Recommended MCP Servers

View more MCP servers

Take It Further

Maximize your productivity with these powerful resources

📋

Define Your Standards

Set up coding standards to ensure this workflow produces consistent, high-quality results.

Browse Rules Library
📖

Master Workflows

Learn how to create custom workflows, use Turbo Mode, and build your automation library.

Complete Guide

How to use this Skill in Claude Code & Cursor

For Claude Code (CLI)

To use this skill in Claude Code, copy the rule content into your project's custom instructions or follow our Add-Skill CLI guide. This ensures Claude follows your standards during every code generation.

For Cursor & Windsurf

For Cursor or Windsurf, individual skills are best used in the "Rules for AI" section. This specific unit helps the agent avoid devops & ci/cd issues, leading to cleaner, more efficient code.

Why the skill format matters: the standardized Agent Skills format lets your AI agent load detailed instructions only when they are relevant, keeping your prompt clean while improving results.

Source & attribution

This skill is categorized under DevOps & CI/CD and is published by W. Shobson, maintained in wshobson/agents.

← Browse All Agent Skills
Sponsored AI assistant. Recommendations may be paid.