Skip to content
Back to skills

476 Integration 253dc85f

CSecurity

Complete guide for integrating ShellCheck into development workflows.

  • 9 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added June 1, 2026
devopsshellbashdockerazuretestinggitdevopsci/cd

Works with

  • vscode
  • cli

Security analysis

C63/100
  • criticalPipes output to a shell interpreter
  • criticalPipes output to a shell interpreter
  • criticalAccesses sensitive system or user directories

Pro scans all 2 files and shows the line behind each finding

Scanned June 1, 2026

npx -y skills add tools-only/X-Skills --skill 476-integration_253dc85f --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of 476 Integration 253dc85f?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for 476 Integration 253dc85f
[![Security: C — Skills Directory](https://www.skillsdirectory.com/api/skills/tools-only-476-integration-253dc85f/badge)](https://www.skillsdirectory.com/skills/tools-only-476-integration-253dc85f)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
# ShellCheck CI/CD Integration Guide

Complete guide for integrating ShellCheck into development workflows.

## Pre-commit Hooks

### Official Pre-commit Hook

Add to `.pre-commit-config.yaml`:

```yaml
repos:
  - repo: https://github.com/koalaman/shellcheck-precommit
    rev: v0.11.0
    hooks:
      - id: shellcheck
        # Optional: customize arguments
        args: ["--severity=warning"]
```

### Alternative: shellcheck-py

```yaml
repos:
  - repo: https://github.com/shellcheck-py/shellcheck-py
    rev: v0.9.0.5
    hooks:
      - id: shellcheck
```

### Custom Pre-commit Script

```bash
#!/bin/bash
# .git/hooks/pre-commit

# Find all staged shell scripts
staged_scripts=$(git diff --cached --name-only --diff-filter=ACMR | grep -E '\.(sh|bash|zsh)$')

if [[ -n "$staged_scripts" ]]; then
    echo "Running ShellCheck on staged scripts..."

    # Run shellcheck on all staged scripts
    if ! echo "$staged_scripts" | xargs shellcheck; then
        echo "ShellCheck found issues. Please fix them before committing."
        exit 1
    fi
fi

exit 0
```

Make executable:
```bash
chmod +x .git/hooks/pre-commit
```

## GitHub Actions

### Basic Workflow

```yaml
# .github/workflows/shellcheck.yml
name: ShellCheck

on:
  push:
    branches: [main, develop]
    paths:
      - '**.sh'
      - '**.bash'
  pull_request:
    paths:
      - '**.sh'
      - '**.bash'

jobs:
  shellcheck:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Run ShellCheck
        uses: ludeeus/action-shellcheck@master
        with:
          severity: warning
          scandir: './scripts'
          format: gcc
          additional_files: 'entrypoint'
```

### Advanced Workflow with Annotations

```yaml
name: ShellCheck

on: [push, pull_request]

jobs:
  shellcheck:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Install ShellCheck
        run: sudo apt-get install -y shellcheck

      - name: Find shell scripts
        id: scripts
        run: |
          scripts=$(find . -type f \( -name "*.sh" -o -name "*.bash" \) ! -path "./.git/*")
          echo "scripts<<EOF" >> $GITHUB_OUTPUT
          echo "$scripts" >> $GITHUB_OUTPUT
          echo "EOF" >> $GITHUB_OUTPUT

      - name: Run ShellCheck
        run: |
          echo "${{ steps.scripts.outputs.scripts }}" | xargs shellcheck -f gcc || true

      - name: ShellCheck with annotations
        run: |
          echo "${{ steps.scripts.outputs.scripts }}" | xargs shellcheck -f json | \
            jq -r '.[] | "::warning file=\(.file),line=\(.line),col=\(.column)::\(.message) [\(.code)]"'
```

### Matrix Testing Multiple Shells

```yaml
name: ShellCheck Multi-Shell

on: [push, pull_request]

jobs:
  shellcheck:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        shell: [sh, bash, dash, ksh]
    steps:
      - uses: actions/checkout@v4

      - name: Run ShellCheck for ${{ matrix.shell }}
        run: |
          find ./scripts -name "*.sh" -exec shellcheck -s ${{ matrix.shell }} {} +
```

## GitLab CI/CD

### Basic Pipeline

```yaml
# .gitlab-ci.yml
shellcheck:
  image: koalaman/shellcheck-alpine:stable
  stage: test
  script:
    - find . -name "*.sh" -exec shellcheck {} +
  only:
    changes:
      - "**/*.sh"
```

### With Artifacts

```yaml
shellcheck:
  image: koalaman/shellcheck-alpine:stable
  stage: lint
  script:
    - find . -name "*.sh" -print0 | xargs -0 shellcheck -f checkstyle > shellcheck-report.xml || true
  artifacts:
    reports:
      junit: shellcheck-report.xml
    paths:
      - shellcheck-report.xml
    expire_in: 1 week
```

## Jenkins

### Declarative Pipeline

```groovy
pipeline {
    agent any

    stages {
        stage('ShellCheck') {
            steps {
                sh '''
                    find . -name "*.sh" | xargs shellcheck -f checkstyle > shellcheck.xml || true
                '''
            }
            post {
                always {
                    recordIssues tools: [checkStyle(pattern: 'shellcheck.xml')]
                }
            }
        }
    }
}
```

### With Docker

```groovy
pipeline {
    agent {
        docker {
            image 'koalaman/shellcheck-alpine:stable'
        }
    }

    stages {
        stage('Lint') {
            steps {
                sh 'find . -name "*.sh" -exec shellcheck {} +'
            }
        }
    }
}
```

## CircleCI

```yaml
# .circleci/config.yml
version: 2.1

orbs:
  shellcheck: circleci/shellcheck@3.2.0

workflows:
  lint:
    jobs:
      - shellcheck/check:
          dir: ./scripts
          severity: warning
          exclude: SC1091
```

## Travis CI

```yaml
# .travis.yml
language: shell

addons:
  apt:
    packages:
      - shellcheck

script:
  - find . -name "*.sh" -exec shellcheck {} +
```

## Azure DevOps

```yaml
# azure-pipelines.yml
trigger:
  paths:
    include:
      - '**/*.sh'

pool:
  vmImage: 'ubuntu-latest'

steps:
  - task: Bash@3
    displayName: 'Install ShellCheck'
    inputs:
      targetType: 'inline'
      script: |
        sudo apt-get update
        sudo apt-get install -y shellcheck

  - task: Bash@3
    displayName: 'Run ShellCheck'
    inputs:
      targetType: 'inline'
      script: |
        find . -name "*.sh" -exec shellcheck -f gcc {} +
```

## Makefile Integration

```makefile
# Makefile

SHELL_SCRIPTS := $(shell find . -name "*.sh" -not -path "./.git/*")

.PHONY: lint lint-fix check-shellcheck

# Check if shellcheck is installed
check-shellcheck:
	@command -v shellcheck >/dev/null 2>&1 || { echo "shellcheck not installed. Run: brew install shellcheck"; exit 1; }

# Run shellcheck
lint: check-shellcheck
	@echo "Running ShellCheck on $(words $(SHELL_SCRIPTS)) scripts..."
	@shellcheck $(SHELL_SCRIPTS)

# Run with severity filter
lint-warnings: check-shellcheck
	@shellcheck -S warning $(SHELL_SCRIPTS)

lint-errors: check-shellcheck
	@shellcheck -S error $(SHELL_SCRIPTS)

# Generate diff for auto-fixes
lint-fix: check-shellcheck
	@shellcheck -f diff $(SHELL_SCRIPTS) | patch -p1

# Generate JSON report
lint-report: check-shellcheck
	@shellcheck -f json $(SHELL_SCRIPTS) > shellcheck-report.json

# CI mode - fail on any issue
ci-lint: check-shellcheck
	@shellcheck -S warning -f gcc $(SHELL_SCRIPTS)
```

## Editor Integration

### VS Code

Install `vscode-shellcheck` extension:

```json
// .vscode/settings.json
{
  "shellcheck.enable": true,
  "shellcheck.run": "onSave",
  "shellcheck.executablePath": "shellcheck",
  "shellcheck.exclude": ["SC1091"],
  "shellcheck.customArgs": ["-x"]
}
```

### Vim/Neovim with ALE

```vim
" ~/.vimrc or init.vim
let g:ale_linters = {
\   'sh': ['shellcheck'],
\   'bash': ['shellcheck'],
\}

let g:ale_sh_shellcheck_options = '-x'
let g:ale_sh_shellcheck_exclusions = 'SC1091'
```

### Neovim with nvim-lint

```lua
-- lua/plugins/lint.lua
require('lint').linters_by_ft = {
  sh = {'shellcheck'},
  bash = {'shellcheck'},
}

require('lint').linters.shellcheck.args = {
  '-x',
  '-f', 'gcc',
  '-',
}
```

### Emacs with Flycheck

```elisp
;; ~/.emacs.d/init.el
(use-package flycheck
  :ensure t
  :init (global-flycheck-mode)
  :config
  (setq flycheck-shellcheck-follow-sources nil)
  (add-to-list 'flycheck-disabled-checkers 'sh-posix-dash))
```

### Sublime Text

Install `SublimeLinter-shellcheck` via Package Control.

## Docker Usage

### Basic Docker Run

```bash
# Check single file
docker run --rm -v "$PWD:/mnt" koalaman/shellcheck:stable /mnt/script.sh

# Check directory
docker run --rm -v "$PWD:/mnt" koalaman/shellcheck:stable /mnt/**/*.sh

# With options
docker run --rm -v "$PWD:/mnt" \
  -e SHELLCHECK_OPTS='-x -S warning' \
  koalaman/shellcheck:stable /mnt/scripts/*.sh
```

### Docker Compose

```yaml
# docker-compose.yml
version: '3.8'

services:
  shellcheck:
    image: koalaman/shellcheck:stable
    volumes:
      - ./:/mnt:ro
      - ./.shellcheckrc:/root/.shellcheckrc:ro
    command: /mnt/scripts/*.sh
```

### Multi-stage Dockerfile with ShellCheck

```dockerfile
# Dockerfile
FROM koalaman/shellcheck:stable AS shellcheck
COPY scripts/ /scripts/
RUN shellcheck /scripts/*.sh

FROM ubuntu:22.04
COPY --from=shellcheck /scripts/ /app/scripts/
# ... rest of build
```

## Quality Gate Integration

### SonarQube

Use CheckStyle format and import:

```bash
shellcheck -f checkstyle *.sh > shellcheck-checkstyle.xml
```

### Codacy

ShellCheck is natively supported. Enable in repository settings.

### Code Climate

Add to `.codeclimate.yml`:

```yaml
version: "2"
plugins:
  shellcheck:
    enabled: true
    config:
      severity: warning
```

### CodeFactor

ShellCheck is enabled by default for shell scripts.

Files in this skill

  • README.md875 B
  • skill.md8.4 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.