Bash Syntax Check in GitHub Actions
Catch Bash script bugs before they hit main. This guide gives you copy-paste YAML for running ShellCheck and bash -n in GitHub Actions and GitLab CI, plus the trade-offs versus an online bash syntax checker.
Minimal GitHub Actions workflow with ShellCheck
Create .github/workflows/shellcheck.yml with: `name: shellcheck` / `on: [push, pull_request]` / `jobs: shellcheck: runs-on: ubuntu-latest` / `steps:` then `- uses: actions/checkout@v4` and `- uses: ludeeus/action-shellcheck@master` with `with: severity: warning`. The ludeeus action auto-discovers every .sh file in the repo and runs ShellCheck against it. The job fails on any warning or higher, blocking merges on pull requests when branch protection is on.
Adding a parser-only smoke test with bash -n
ShellCheck catches semantic issues; `bash -n script.sh` is a fast syntax-only parse check that costs ~50ms per script. Add it as a second step: `- name: Bash parse check` / `run: find . -name "*.sh" -print0 | xargs -0 -n1 bash -n`. This catches missing fi/done/esac before ShellCheck even loads. Useful for repos with many tiny scripts where ShellCheck would be overkill.
GitLab CI equivalent
In .gitlab-ci.yml: `shellcheck: image: koalaman/shellcheck-alpine:latest` / `script: shellcheck -S warning $(find . -name "*.sh")`. Same idea — discover scripts, run ShellCheck, fail the pipeline on warnings. Cache the image layer for sub-second job starts after the first run.
When to use CI vs an online bash checker
CI is for scripts that live in your repo and run as part of your build. Use an online bash syntax checker for one-off scripts: install.sh files you found in a gist, snippets from Stack Overflow, customer-supplied automation, or anything you do not control. The online checker is also useful during PR review when you want a second opinion without cloning the branch locally.
Pre-commit hook for instant local feedback
Install pre-commit (pip install pre-commit), then add to .pre-commit-config.yaml: `- repo: https://github.com/koalaman/shellcheck-precommit` / `rev: v0.10.0` / `hooks: - id: shellcheck`. Now ShellCheck runs on every git commit and rejects bad scripts locally — much faster than waiting for CI.
Frequently asked questions
- Does ShellCheck slow down CI?
- No — the ludeeus action typically completes in under 15 seconds for a few hundred scripts. It is one of the cheapest CI jobs you can add.
- How do I ignore a specific ShellCheck rule?
- Add `# shellcheck disable=SC2086` directly above the offending line, or pass `--exclude=SC2086` to ShellCheck globally. Prefer line-level disables so the rest of the file stays checked.
- Can I run the same checks the online tool runs in CI?
- Bash Checker is a hosted analyzer and does not currently ship a CLI. Use ShellCheck in CI for the equivalent core rules, and use Bash Checker online for the extra security and quality dimensions when reviewing individual scripts.