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 git
    
  • Fedora/RHEL (dnf):

    sudo dnf install -y ShellCheck shfmt curl jq git
    
  • openSUSE (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 pipefail and IFS=$'\n\t'
    • Validate arguments and paths
    • Quote variables
    • Use rsync -a -- instead of raw cp -r
    • Provide a minimal diff and 3–5 tests (spaces in paths, permission errors, non-existent src, full disk, etc.)

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.