skills/shellcheck-configuration/SKILL.md
Master ShellCheck static analysis configuration and usage for shell script quality. Use when setting up linting infrastructure, fixing code issues, or ensuring script portability.
npx skillsauth add ruanmalvao-web/lp shellcheck-configurationInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Comprehensive guidance for configuring and using ShellCheck to improve shell script quality, catch common pitfalls, and enforce best practices through static code analysis.
resources/implementation-playbook.md.ShellCheck is a static analysis tool that analyzes shell scripts and detects problematic patterns. It supports:
# 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
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
# Set default shell target
export SHELLCHECK_SHELL=bash
# Enable strict mode
export SHELLCHECK_STRICT=true
# Specify configuration file location
export SHELLCHECK_CONFIG=~/.shellcheckrc
# 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
# 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
# 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 )
# 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
}
#!/bin/bash
# Configure for maximum portability
shellcheck \
--shell=sh \
--external-sources \
--check-sourced \
script.sh
#!/bin/bash
# Configure for Bash development
shellcheck \
--shell=bash \
--exclude=SC1091,SC2119 \
--enable=all \
script.sh
#!/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
# 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
#!/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
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 {} \;
shellcheck:
stage: lint
image: koalaman/shellcheck-alpine
script:
- find . -type f -name "*.sh" -exec shellcheck {} \;
allow_failure: false
#!/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
# 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
# Problem
some_command
if [ $? -eq 0 ]; then
echo "success"
fi
# Solution
if some_command; then
echo "success"
fi
# Problem
[ -f "$file" ] && echo "exists" || echo "not found"
# Solution - clearer intent
if [ -f "$file" ]; then
echo "exists"
else
echo "not found"
fi
# Problem
echo 'Variable value: $VAR'
# Solution
echo "Variable value: $VAR"
# 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
#!/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]
shellcheck --format=gcc script.sh
# Output:
# script.sh:1:3: warning: foo is referenced but not assigned.
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
--enable=all with careful exclusionstools
No-code automation democratizes workflow building. Zapier and Make (formerly Integromat) let non-developers automate business processes without writing code. But no-code doesn't mean no-complexity - these platforms have their own patterns, pitfalls, and breaking points. This skill covers when to use which platform, how to build reliable automations, and when to graduate to code-based solutions. Key insight: Zapier optimizes for simplicity and integrations (7000+ apps), Make optimizes for power
tools
This skill should be used when the user asks to "test for XSS vulnerabilities", "perform cross-site scripting attacks", "identify HTML injection flaws", "exploit client-side injection vulnerabilities", "steal cookies via XSS", or "bypass content security policies". It provides comprehensive techniques for detecting, exploiting, and understanding XSS and HTML injection attack vectors in web applications.
development
Comprehensive spreadsheet creation, editing, and analysis with support for formulas, formatting, data analysis, and visualization. When Claude needs to work with spreadsheets (.xlsx, .xlsm, .csv, .tsv, etc) for: (1) Creating new spreadsheets with formulas and formatting, (2) Reading or analyzing data, (3) Modify existing spreadsheets while preserving formulas, (4) Data analysis and visualization in spreadsheets, or (5) Recalculating formulas
tools
Publish articles to X/Twitter