shellcheck-configuration
upstream

Master ShellCheck static analysis configuration and usage for shell script quality. Use when setting up linting infrastructure, fixing code issues, or ensuring script portability.

ID: shellcheck-configuration
Preview
Codigo

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


``bash

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


`bash

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

`bash

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


`bash

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


`bash

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


`bash

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)


`bash

#!/bin/bash

Configure for maximum portability


shellcheck \

--shell=sh \

--external-sources \

--check-sourced \

script.sh

`


Development Configuration (Bash with Relaxed Rules)


`bash

#!/bin/bash

Configure for Bash development


shellcheck \

--shell=bash \

--exclude=SC1091,SC2119 \

--enable=all \

script.sh

`


CI/CD Integration Configuration


`bash

#!/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


`bash

#!/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


`yaml

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


`yaml

shellcheck:

stage: lint

image: koalaman/shellcheck-alpine

script:

- find . -type f -name "*.sh" -exec shellcheck {} \;

allow_failure: false

`


Handling ShellCheck Violations


Suppressing Specific Warnings


`bash

#!/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


`bash

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


`bash

Problem

some_command

if [ $? -eq 0 ]; then

echo "success"

fi


Solution

if some_command; then

echo "success"

fi

`


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


`bash

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


`bash

Problem

echo 'Variable value: $VAR'


Solution

echo "Variable value: $VAR"

`


#### SC2009: Use pgrep instead of grep


`bash

Problem

ps aux | grep -v grep | grep myprocess


Solution

pgrep -f myprocess

`


Performance Optimization


Checking Multiple Files


`bash

#!/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


`bash

#!/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


`bash

shellcheck script.sh


Output:

script.sh:1:3: warning: foo is referenced but not assigned. [SC2154]

`


GCC Format (for CI/CD)


`bash

shellcheck --format=gcc script.sh


Output:

script.sh:1:3: warning: foo is referenced but not assigned.

`


JSON Format (for parsing)


`bash

shellcheck --format=json script.sh


Output:

[{"file": "script.sh", "line": 1, "column": 3, "level": "warning", "code": 2154, "message": "..."}]

`


Quiet Format


`bash

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/

Informacion

Estado
Activo
Origen upstream
Usos 3
Ultimo uso 23/01 16:57
Actualizado 09/01/2026 02:14

Archivo origen

Z:\Repositorios\core\upstream\plugins\shell-scripting\skills\shellcheck-configuration\SKILL.md