Shellcheck Configuration

Configure ShellCheck for bulletproof shell script quality control

✨ The solution you've been looking for

Verified
Tested and verified by our team
25450 Stars

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 shell-scripting static-analysis code-quality bash ci-cd linting devops
Repository

See It In Action

Interactive preview & real-world examples

Live Demo
Skill Demo Animation

AI Conversation Simulator

See how users interact with this skill

User Prompt

Help me configure ShellCheck in a GitHub Actions workflow to lint all shell scripts in my repository and fail the build if issues are found

Skill Processing

Analyzing request...

Agent Response

Complete workflow configuration with proper error handling and reporting that prevents merging scripts with quality issues

Quick Start (3 Steps)

Get up and running in minutes

1

Install

claude-code skill install shellcheck-configuration

claude-code skill install shellcheck-configuration
2

Config

3

First Trigger

@shellcheck-configuration help

Commands

CommandDescriptionRequired Args
@shellcheck-configuration ci/cd-pipeline-integrationSet up automated shell script linting in your continuous integration pipeline to catch issues before deploymentNone
@shellcheck-configuration legacy-script-quality-assessmentAnalyze and improve existing shell scripts by understanding and fixing ShellCheck violationsNone
@shellcheck-configuration team-development-standardsEstablish consistent shell scripting standards across development teams with proper ShellCheck configurationNone

Typical Use Cases

CI/CD Pipeline Integration

Set up automated shell script linting in your continuous integration pipeline to catch issues before deployment

Legacy Script Quality Assessment

Analyze and improve existing shell scripts by understanding and fixing ShellCheck violations

Team Development Standards

Establish consistent shell scripting standards across development teams with proper ShellCheck configuration

Overview

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

 1# macOS with Homebrew
 2brew install shellcheck
 3
 4# Ubuntu/Debian
 5apt-get install shellcheck
 6
 7# From source
 8git clone https://github.com/koalaman/shellcheck.git
 9cd shellcheck
10make build
11make install
12
13# Verify installation
14shellcheck --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

1# Set default shell target
2export SHELLCHECK_SHELL=bash
3
4# Enable strict mode
5export SHELLCHECK_STRICT=true
6
7# Specify configuration file location
8export SHELLCHECK_CONFIG=~/.shellcheckrc

Common ShellCheck Error Codes

SC1000-1099: Parser Errors

1# SC1004: Backslash continuation not followed by newline
2echo hello\
3world  # Error - needs line continuation
4
5# SC1008: Invalid data for operator `=='
6if [[ $var =  "value" ]]; then  # Space before ==
7    true
8fi

SC2000-2099: Shell Issues

 1# SC2009: Consider using pgrep or pidof instead of grep|grep
 2ps aux | grep -v grep | grep myprocess  # Use pgrep instead
 3
 4# SC2012: Use `ls` only for viewing. Use `find` for reliable output
 5for file in $(ls -la)  # Better: use find or globbing
 6
 7# SC2015: Avoid using && and || instead of if-then-else
 8[[ -f "$file" ]] && echo "found" || echo "not found"  # Less clear
 9
10# SC2016: Expressions don't expand in single quotes
11echo '$VAR'  # Literal $VAR, not variable expansion
12
13# SC2026: This word is non-standard. Set POSIXLY_CORRECT
14# when using with scripts for other shells

SC2100-2199: Quoting Issues

 1# SC2086: Double quote to prevent globbing and word splitting
 2for i in $list; do  # Should be: for i in $list or for i in "$list"
 3    echo "$i"
 4done
 5
 6# SC2115: Literal tilde in path not expanded. Use $HOME instead
 7~/.bashrc  # In strings, use "$HOME/.bashrc"
 8
 9# SC2181: Check exit code directly with `if`, not indirectly in a list
10some_command
11if [ $? -eq 0 ]; then  # Better: if some_command; then
12
13# SC2206: Quote to prevent word splitting or set IFS
14array=( $items )  # Should use: array=( $items )

SC3000-3999: POSIX Compliance Issues

1# SC3010: In POSIX sh, use 'case' instead of 'cond && foo'
2[[ $var == "value" ]] && do_something  # Not POSIX
3
4# SC3043: In POSIX sh, use 'local' is undefined
5function my_func() {
6    local var=value  # Not POSIX in some shells
7}

Practical Configuration Examples

Minimal Configuration (Strict POSIX)

1#!/bin/bash
2# Configure for maximum portability
3
4shellcheck \
5  --shell=sh \
6  --external-sources \
7  --check-sourced \
8  script.sh

Development Configuration (Bash with Relaxed Rules)

1#!/bin/bash
2# Configure for Bash development
3
4shellcheck \
5  --shell=bash \
6  --exclude=SC1091,SC2119 \
7  --enable=all \
8  script.sh

CI/CD Integration Configuration

 1#!/bin/bash
 2set -Eeuo pipefail
 3
 4# Analyze all shell scripts and fail on issues
 5find . -type f -name "*.sh" | while read -r script; do
 6    echo "Checking: $script"
 7    shellcheck \
 8        --shell=bash \
 9        --format=gcc \
10        --exclude=SC1091 \
11        "$script" || exit 1
12done

.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

 1#!/bin/bash
 2# .git/hooks/pre-commit
 3
 4#!/bin/bash
 5set -e
 6
 7# Find all shell scripts changed in this commit
 8git diff --cached --name-only | grep '\.sh$' | while read -r script; do
 9    echo "Linting: $script"
10
11    if ! shellcheck "$script"; then
12        echo "ShellCheck failed on $script"
13        exit 1
14    fi
15done

GitHub Actions Workflow

 1name: ShellCheck
 2
 3on: [push, pull_request]
 4
 5jobs:
 6  shellcheck:
 7    runs-on: ubuntu-latest
 8
 9    steps:
10      - uses: actions/checkout@v3
11
12      - name: Run ShellCheck
13        run: |
14          sudo apt-get install shellcheck
15          find . -type f -name "*.sh" -exec shellcheck {} \;

GitLab CI Pipeline

1shellcheck:
2  stage: lint
3  image: koalaman/shellcheck-alpine
4  script:
5    - find . -type f -name "*.sh" -exec shellcheck {} \;
6  allow_failure: false

Handling ShellCheck Violations

Suppressing Specific Warnings

 1#!/bin/bash
 2
 3# Disable warning for entire line
 4# shellcheck disable=SC2086
 5for file in $(ls -la); do
 6    echo "$file"
 7done
 8
 9# Disable for entire script
10# shellcheck disable=SC1091,SC2119
11
12# Disable multiple warnings (format varies)
13command_that_fails() {
14    # shellcheck disable=SC2015
15    [ -f "$1" ] && echo "found" || echo "not found"
16}
17
18# Disable specific check for source directive
19# shellcheck source=./helper.sh
20source helper.sh

Common Violations and Fixes

SC2086: Double quote to prevent word splitting

1# Problem
2for i in $list; do done
3
4# Solution
5for i in $list; do done  # If $list is already quoted, or
6for i in "${list[@]}"; do done  # If list is an array

SC2181: Check exit code directly

 1# Problem
 2some_command
 3if [ $? -eq 0 ]; then
 4    echo "success"
 5fi
 6
 7# Solution
 8if some_command; then
 9    echo "success"
10fi

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

1# Problem
2[ -f "$file" ] && echo "exists" || echo "not found"
3
4# Solution - clearer intent
5if [ -f "$file" ]; then
6    echo "exists"
7else
8    echo "not found"
9fi

SC2016: Expressions don’t expand in single quotes

1# Problem
2echo 'Variable value: $VAR'
3
4# Solution
5echo "Variable value: $VAR"

SC2009: Use pgrep instead of grep

1# Problem
2ps aux | grep -v grep | grep myprocess
3
4# Solution
5pgrep -f myprocess

Performance Optimization

Checking Multiple Files

 1#!/bin/bash
 2
 3# Sequential checking
 4for script in *.sh; do
 5    shellcheck "$script"
 6done
 7
 8# Parallel checking (faster)
 9find . -name "*.sh" -print0 | \
10    xargs -0 -P 4 -n 1 shellcheck

Caching Results

 1#!/bin/bash
 2
 3CACHE_DIR=".shellcheck_cache"
 4mkdir -p "$CACHE_DIR"
 5
 6check_script() {
 7    local script="$1"
 8    local hash
 9    local cache_file
10
11    hash=$(sha256sum "$script" | cut -d' ' -f1)
12    cache_file="$CACHE_DIR/$hash"
13
14    if [[ ! -f "$cache_file" ]]; then
15        if shellcheck "$script" > "$cache_file" 2>&1; then
16            touch "$cache_file.ok"
17        else
18            return 1
19        fi
20    fi
21
22    [[ -f "$cache_file.ok" ]]
23}
24
25find . -name "*.sh" | while read -r script; do
26    check_script "$script" || exit 1
27done

Output Formats

Default Format

1shellcheck script.sh
2
3# Output:
4# script.sh:1:3: warning: foo is referenced but not assigned. [SC2154]

GCC Format (for CI/CD)

1shellcheck --format=gcc script.sh
2
3# Output:
4# script.sh:1:3: warning: foo is referenced but not assigned.

JSON Format (for parsing)

1shellcheck --format=json script.sh
2
3# Output:
4# [{"file": "script.sh", "line": 1, "column": 3, "level": "warning", "code": 2154, "message": "..."}]

Quiet Format

1shellcheck --format=quiet script.sh
2
3# 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

What Users Are Saying

Real feedback from the community

Environment Matrix

Dependencies

ShellCheck (latest stable version recommended)
Bash 4.0+ or POSIX shell for target analysis

Framework Support

GitHub Actions ✓ (recommended) GitLab CI ✓ Jenkins ✓ Pre-commit hooks ✓

Context Window

Token Usage ~1K-3K tokens for typical configuration scenarios

Security & Privacy

Information

Author
wshobson
Updated
2026-01-30
Category
automation-tools