- Posted on
- • Artificial Intelligence
Artificial Intelligence Code Quality Checks
- Author
-
-
- User
- linuxbash
- Posts by this author
- Posts by this author
-
AI-Assisted Code Quality Checks for Bash on Linux
Ever shipped a shell script that “worked on your machine” but woke you up at 3 AM in production? Static linters like ShellCheck catch a ton of issues—but they don’t always explain the deeper “why,” suggest safer patterns, or generate tests. That’s where Artificial Intelligence can help: pair deterministic linters with an AI reviewer to get prioritized, human-readable feedback and concrete fixes—right in your terminal.
This article shows you how to:
Set up rock-solid Bash quality checks (formatting + linting)
Add an AI review step you can run locally with curl
Automate everything in Git hooks/CI
Keep it safe: no secrets, reproducible prompts, and traceable output
Whether you’re maintaining scripts for ops, packaging, or CI pipelines, this workflow tightens quality without slowing you down.
Why combine linters with AI?
Linters are precise but literal. They catch token-level pitfalls (unsafe globbing, unquoted variables) and enforce formatting.
AI is contextual. It can summarize many linter warnings, propose safer refactors, and even draft tests or migration plans.
Together: deterministic guardrails + human-like review = fewer regressions, clearer code reviews, and faster learning for the team.
1) Baseline your shell: formatting + linting
Install the essentials (ShellCheck, shfmt, curl, jq, git). Use your distro’s package manager:
Debian/Ubuntu (apt):
sudo apt update sudo apt install -y shellcheck shfmt curl jq gitFedora/RHEL (dnf):
sudo dnf install -y ShellCheck shfmt curl jq gitopenSUSE (zypper):
sudo zypper refresh sudo zypper install -y ShellCheck shfmt curl jq git
Quick usage:
# Format in-place
shfmt -w script.sh
# Lint with actionable warnings
shellcheck script.sh
# Lint all scripts in a repo
git ls-files '*.sh' | xargs -r shellcheck
Pro tip: enforce formatting in CI with:
shfmt -d .
This exits non-zero when diffs are needed.
2) Add an AI reviewer in your terminal (curl + jq)
The idea: run ShellCheck, gather your script and diagnostics, then ask an AI model to:
Prioritize issues by risk
Propose minimal safe fixes (with diffs)
Suggest tests for edge cases
You can call an “OpenAI-compatible” API with curl (many providers are compatible). Define these environment variables to fit your provider:
export AI_API_URL="https://api.openai.com/v1/chat/completions" # or your provider’s compatible endpoint
export AI_MODEL="gpt-4o-mini" # or any model you prefer
export AI_API_KEY="sk-..." # store securely (e.g., in your shell keyring)
Create a review script named ai-review.sh:
#!/usr/bin/env bash
set -euo pipefail
if [[ $# -lt 1 ]]; then
echo "Usage: $0 path/to/script.sh" >&2
exit 2
fi
file="$1"
if [[ ! -f "$file" ]]; then
echo "File not found: $file" >&2
exit 2
fi
# Ensure prerequisites
for cmd in shellcheck jq curl; do
command -v "$cmd" >/dev/null || { echo "Missing dependency: $cmd" >&2; exit 3; }
done
# Run linters
lint_json="$(shellcheck -f json "$file" 2>/dev/null || echo '[]')"
# Read script content and scrub obvious secrets before sending to AI
code="$(sed \
-e 's/\(AWS_SECRET_ACCESS_KEY=\).*/\1[REDACTED]/' \
-e 's/\(AWS_ACCESS_KEY_ID=\).*/\1[REDACTED]/' \
-e 's/\(password\|passwd\|token\)=[^[:space:]]\+/\1=[REDACTED]/Ig' \
"$file"
)"
# Build the prompt
read -r -d '' PROMPT <<'EOF' || true
You are a senior Bash/Shell code reviewer.
Goals:
- Prioritize issues by security risk and production impact.
- Propose minimal, safe fixes (quote variables, use set -euo pipefail, avoid command injection).
- Provide a concise patch (unified diff) and justifications.
- Suggest 3–5 tests or edge cases to validate changes.
Constraints:
- Only change what is necessary.
- Preserve semantics unless behavior is obviously unsafe.
Now review the script and the linter output.
EOF
payload="$(jq -n \
--arg model "${AI_MODEL:-gpt-4o-mini}" \
--arg sys "You are an expert Linux/Bash reviewer focusing on safety, POSIX compatibility, and reliability." \
--arg prompt "$PROMPT" \
--arg code "$code" \
--argjson lint "$lint_json" \
'{
model: $model,
messages: [
{role:"system", content:$sys},
{role:"user", content: ($prompt + "\n\n=== SCRIPT START ===\n" + $code + "\n=== SCRIPT END ===\n\n=== LINTER(JSON) ===\n" + ($lint|tostring))}
],
temperature: 0.2
}'
)"
: "${AI_API_URL:?Set AI_API_URL}"
: "${AI_API_KEY:?Set AI_API_KEY}"
resp="$(curl -sS -X POST "$AI_API_URL" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $AI_API_KEY" \
-d "$payload")"
# Try to print the assistant message for OpenAI-compatible responses
echo "$resp" | jq -r '.choices[0].message.content // .error.message // "No content"'
Make it executable:
chmod +x ai-review.sh
Run it:
./ai-review.sh ./script.sh
Notes:
Keep secrets out of prompts. The sample sed rules redact typical keys; extend to match your environment.
Pin a model version (e.g., vendor-2024-06-xx) for reproducibility when your provider supports it.
Save the raw response to logs in CI if you need auditability.
3) Automate with Git hooks (pre-push)
Wire the checks into your flow so they run when it matters. A lightweight pre-push hook can block risky scripts and nudge contributors to fix them before reviews.
Create .git/hooks/pre-push:
#!/usr/bin/env bash
set -euo pipefail
# Only scan changed shell files
changed="$(git diff --name-only --cached | grep -E '\.sh$' || true)"
[ -z "$changed" ] && exit 0
echo "==> Formatting check (shfmt)"
if ! shfmt -d $changed; then
echo "Please run: shfmt -w $changed"
exit 1
fi
echo "==> Linting (ShellCheck)"
if ! shellcheck $changed; then
echo "ShellCheck found issues. Please fix or re-run after edits."
# Not exiting here lets AI still offer a plan; uncomment to hard-fail:
# exit 1
fi
echo "==> AI review (informational)"
for f in $changed; do
echo "--- Review for $f ---"
./ai-review.sh "$f" || echo "AI review skipped (configure AI_API_URL/AI_API_KEY)"
echo
done
echo "All checks complete."
Make it executable:
chmod +x .git/hooks/pre-push
If you prefer a stricter gate, make AI review a hard fail by checking its response (e.g., for “HIGH RISK”) and exiting non-zero.
4) Use AI for tests and edge cases
AI is great at thinking up ways your script might break. Add a helper to propose tests you can port into your CI:
#!/usr/bin/env bash
set -euo pipefail
f="${1:?Usage: $0 path/to/script.sh}"
prompt="Given this Bash script, list 5 edge-case test scenarios with exact commands and expected outcomes. Focus on permissions, missing files, spaces/newlines in paths, slow/failed network calls, and locale/IFS weirdness."
code="$(cat "$f")"
payload="$(jq -n \
--arg model "${AI_MODEL:-gpt-4o-mini}" \
--arg sys "You are an expert Linux tester focusing on robust shell scripts." \
--arg prompt "$prompt" \
--arg code "$code" \
'{
model: $model,
messages: [
{role:"system", content:$sys},
{role:"user", content: ($prompt + "\n\n=== SCRIPT ===\n" + $code)}
],
temperature: 0.2
}'
)"
curl -sS -X POST "$AI_API_URL" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $AI_API_KEY" \
-d "$payload" | jq -r '.choices[0].message.content'
Turn its suggestions into bats/shunit2 tests or ad-hoc CI steps.
5) A small real-world example
Imagine a backup script:
#!/usr/bin/env bash
src=$1
dest=/mnt/backup
cp -r $src $dest
echo done
ShellCheck will warn about unquoted variables, missing set -euo pipefail, and potential globbing/injection bugs.
AI review will likely propose:
- Add
set -euo pipefailandIFS=$'\n\t' - Validate arguments and paths
- Quote variables
- Use
rsync -a --instead of rawcp -r - Provide a minimal diff and 3–5 tests (spaces in paths, permission errors, non-existent src, full disk, etc.)
- Add
Run:
shfmt -w backup.sh
shellcheck backup.sh
./ai-review.sh backup.sh
Apply the suggested diff, re-run checks, and you’ve materially improved reliability.
Keep it safe and sane
Don’t send secrets. Redact inputs and consider a local model if required by policy.
Pin model versions and temperature. Save prompts and responses for reproducibility.
Treat AI as advisory unless you’ve validated outputs with tests.
Prefer minimal diffs and justify every change.
Conclusion and next steps
AI won’t replace ShellCheck—but it will turn warnings into prioritized fixes, explain trade-offs, and suggest tests you might miss.
Your 15‑minute quickstart:
1) Install tooling:
- apt:
sudo apt update
sudo apt install -y shellcheck shfmt curl jq git
- dnf:
sudo dnf install -y ShellCheck shfmt curl jq git
- zypper:
sudo zypper refresh
sudo zypper install -y ShellCheck shfmt curl jq git
2) Drop ai-review.sh in your repo and export AI_API_URL, AI_MODEL, AI_API_KEY.
3) Add the pre-push hook.
4) Run it on a flaky script and ship the smallest safe diff.
Call to action: wire this into one of your active repos today. Start with a single script, capture the before/after diffs, and share results with your team. If you want a follow-up post on running a fully local model pipeline, let me know which distro you’re on and your hardware constraints.