Posted on
Artificial Intelligence

Artificial Intelligence Bash Workflow Templates

Author
  • User
    linuxbash
    Posts by this author
    Posts by this author

Artificial Intelligence Bash Workflow Templates: Turn Your Shell into a Smart Assistant

If you spend your day in a terminal, imagine this: your shell drafts clean commit messages, summarizes noisy logs, proposes safe one-liners, and extracts structured JSON from messy text—all on demand. No new GUI. No heavyweight frameworks. Just Bash plus a thin AI wrapper and a few reusable templates.

This article shows why AI-in-the-shell is valid, how to set it up in minutes, and offers 4 ready-to-use workflow templates you can drop into your $PATH today.

Why AI + Bash works

  • Repeatable and auditable: Templates keep prompts/versioning in your dotfiles. You can diff behavior changes and review inputs/outputs.

  • Zero-context switching: Stay in the terminal, pipe text in, and get results out. AI becomes another Unix filter.

  • Vendor-flexible: Point the same templates at a cloud model or a local model (e.g., Ollama) without rewriting your scripts.

  • Lightweight: curl and jq do most of the heavy lifting. Everything else is plain Bash.

Prerequisites and installation

You need curl and jq. Git is handy for the commit template.

  • Debian/Ubuntu (apt):
sudo apt update
sudo apt install -y curl jq git
  • Fedora/RHEL (dnf):
sudo dnf install -y curl jq git
  • openSUSE (zypper):
sudo zypper refresh
sudo zypper install -y curl jq git

Optional: run a local model with Ollama (Linux/macOS). This avoids sending data to a cloud API.

curl -fsSL https://ollama.com/install.sh | sh
# Example: pull a model
ollama pull llama3

Configure environment

Choose a provider: openai (cloud) or ollama (local). Create a small env file.

mkdir -p ~/.config/ai
cat > ~/.config/ai/env <<'EOF'
# Provider: "openai" or "ollama"
export AI_PROVIDER=openai

# Model names:
# - OpenAI examples: gpt-4o-mini, gpt-4o, gpt-4.1-mini (choose what you have access to)
# - Ollama examples: llama3, mistral, codellama
export AI_MODEL=gpt-4o-mini

# Temperature for creativity vs. determinism
export AI_TEMPERATURE=0.2

# Only needed for OpenAI:
# Generate an API key and store it securely (e.g., with a secret manager).
# For quick starts, you can export here, but be mindful of shell history and backups.
export OPENAI_API_KEY="REPLACE_ME"
EOF

Source it in your shell profile or in each script:

. ~/.config/ai/env

A tiny AI library for Bash

Drop this helper into ~/.local/lib/ai.sh. It gives you a single ai_chat function that works with either OpenAI or Ollama.

mkdir -p ~/.local/lib
cat > ~/.local/lib/ai.sh <<'EOF'
#!/usr/bin/env bash
set -euo pipefail

: "${AI_PROVIDER:=openai}"
: "${AI_MODEL:=gpt-4o-mini}"
: "${AI_TEMPERATURE:=0.2}"

need() { command -v "$1" >/dev/null 2>&1 || { echo "Missing dependency: $1" >&2; exit 1; }; }
need curl
need jq

ai_chat() {
  # Usage: ai_chat "system_prompt" "user_prompt"
  local system_prompt="${1:-You are a concise, helpful assistant.}"
  local user_prompt="${2:-}"
  if [[ -z "$user_prompt" ]]; then
    echo "ai_chat usage: ai_chat \"SYSTEM\" \"USER\"" >&2
    return 2
  fi

  case "$AI_PROVIDER" in
    openai)
      : "${OPENAI_API_KEY:?OPENAI_API_KEY is not set}"
      local data
      data=$(jq -n \
        --arg model "$AI_MODEL" \
        --arg sys "$system_prompt" \
        --arg usr "$user_prompt" \
        --argjson temp "$(printf '%s' "$AI_TEMPERATURE" | jq -R 'tonumber')" \
        '{model:$model, temperature:$temp, messages:[{role:"system",content:$sys},{role:"user",content:$usr}]}' )
      curl -sS https://api.openai.com/v1/chat/completions \
        -H "Authorization: Bearer ${OPENAI_API_KEY}" \
        -H "Content-Type: application/json" \
        -d "$data" \
      | jq -r '.choices[0].message.content'
      ;;

    ollama)
      # Ensure ollama is running: `ollama serve` (usually auto-managed by the installer)
      local data
      data=$(jq -n \
        --arg model "$AI_MODEL" \
        --arg sys "$system_prompt" \
        --arg usr "$user_prompt" \
        '{model:$model, messages:[{role:"system",content:$sys},{role:"user",content:$usr}]}' )
      curl -sS http://localhost:11434/api/chat \
        -H "Content-Type: application/json" \
        -d "$data" \
      | jq -r '.message.content'
      ;;

    *)
      echo "Unsupported AI_PROVIDER: $AI_PROVIDER" >&2
      return 2
      ;;
  esac
}
EOF

chmod +x ~/.local/lib/ai.sh

Tip: If you want to keep the system prompt stable across templates, add export SYSTEM_PROMPT in ~/.config/ai/env and pass it to ai_chat.

4 drop-in AI workflow templates

Place these scripts in ~/.local/bin and make them executable. Ensure ~/.local/bin is in your PATH (add to your shell rc if needed).

1) AI-generated Git commit messages (conventional commits)

mkdir -p ~/.local/bin
cat > ~/.local/bin/ai-commit <<'EOF'
#!/usr/bin/env bash
set -euo pipefail
. ~/.config/ai/env
. ~/.local/lib/ai.sh

# Use staged diff if present, else full working diff
diff_output=$(git diff --staged || true)
if [[ -z "$diff_output" ]]; then
  diff_output=$(git diff || true)
fi

if [[ -z "$diff_output" ]]; then
  echo "No changes to describe." >&2
  exit 1
fi

sys="You write high-quality Conventional Commits. Keep subject <= 72 chars. Provide a clear, terse subject and a readable body."
usr=$(cat <<EOT
Summarize the following git diff as a Conventional Commit.
Output:

- First line: <type>(<optional-scope>): <subject>

- Blank line

- Body lines (bulleted or wrapped)

- No code fences, no extra commentary.

Diff:
$diff_output
EOT
)

msg=$(ai_chat "$sys" "$usr")
printf '%s\n' "$msg"
# Uncomment to commit automatically:
# git commit -m "$(printf '%s' "$msg" | sed -n '1p')" -m "$(printf '%s' "$msg" | sed '1d')"
EOF

chmod +x ~/.local/bin/ai-commit

Usage:

git add -A
ai-commit

2) Summarize logs into actionable bullets

cat > ~/.local/bin/ai-summarize-logs <<'EOF'
#!/usr/bin/env bash
set -euo pipefail
. ~/.config/ai/env
. ~/.local/lib/ai.sh

since="${1:-2 hours ago}"
lines="${2:-400}"

# Prefer journalctl if available, else fallback to syslog
if command -v journalctl >/dev/null 2>&1; then
  log=$(journalctl --since "$since" -n "$lines" -o short-iso 2>/dev/null || true)
else
  log=$(tail -n "$lines" /var/log/syslog 2>/dev/null || true)
fi

if [[ -z "$log" ]]; then
  echo "No logs collected." >&2
  exit 1
fi

sys="You are a SRE log analyst. Provide concise, high-signal summaries with concrete pointers."
usr=$(cat <<EOT
Summarize the following logs. Output:

- Top recurring errors/warnings (with counts)

- Notable anomalies and likely root causes

- 3 concrete next steps for investigation/mitigation
Keep it under ~200 words.

Logs:
$log
EOT
)

ai_chat "$sys" "$usr"
EOF

chmod +x ~/.local/bin/ai-summarize-logs

Usage:

ai-summarize-logs "4 hours ago" 600

3) Natural language to safe shell commands (with confirmation)

cat > ~/.local/bin/ai-cmd <<'EOF'
#!/usr/bin/env bash
set -euo pipefail
. ~/.config/ai/env
. ~/.local/lib/ai.sh

if [[ $# -eq 0 ]]; then
  echo "Usage: ai-cmd \"describe what you want to do\"" >&2
  exit 2
fi

request="$*"

sys="You are a shell expert. You ALWAYS return pure JSON only."
usr=$(cat <<EOT
Turn this request into a single safe shell command.

- Prefer read-only commands; if mutation is needed, explain briefly.

- Linux Bash target. Avoid aliases. Use POSIX tools when possible.

- Return ONLY compact JSON: {"cmd":"...","explanation":"...","risk":"low|medium|high"}

Request: $request
EOT
)

resp=$(ai_chat "$sys" "$usr" | sed 's/```json//g;s/```//g' || true)
# Validate JSON and extract fields
if ! echo "$resp" | jq -e . >/dev/null 2>&1; then
  echo "Model did not return valid JSON. Raw output:" >&2
  printf '%s\n' "$resp" >&2
  exit 1
fi

cmd=$(echo "$resp" | jq -r '.cmd')
expl=$(echo "$resp" | jq -r '.explanation')
risk=$(echo "$resp" | jq -r '.risk')

echo "Proposed command:"
echo "  $cmd"
echo
echo "Why: $expl"
echo "Risk: $risk"
echo
read -r -p "Run it? [y/N] " ans
if [[ "${ans:-N}" =~ ^[Yy]$ ]]; then
  bash -lc "$cmd"
else
  echo "Aborted."
fi
EOF

chmod +x ~/.local/bin/ai-cmd

Usage:

ai-cmd "find the 5 largest files under /var/log, human-readable"

4) Extract structured JSON from free text (schema-driven)

cat > ~/.local/bin/ai-extract <<'EOF'
#!/usr/bin/env bash
set -euo pipefail
. ~/.config/ai/env
. ~/.local/lib/ai.sh

if [[ $# -lt 1 ]]; then
  echo "Usage: ai-extract <file-or-> [optional-title]" >&2
  echo "Pass - to read from stdin." >&2
  exit 2
fi

input="$1"
title="${2:-Document}"

if [[ "$input" = "-" ]]; then
  text=$(cat)
else
  text=$(cat -- "$input")
fi

# Define your target schema here
read -r -d '' SCHEMA <<'JSON' || true
{
  "title": "Extracted facts",
  "type": "object",
  "properties": {
    "entities": {
      "type": "array",
      "items": { "type": "string" },
      "description": "Named entities, services, or components mentioned."
    },
    "urls": {
      "type": "array",
      "items": { "type": "string" }
    },
    "config_keys": {
      "type": "array",
      "items": { "type": "string" }
    },
    "summary": {
      "type": "string"
    }
  },
  "required": ["entities", "summary"]
}
JSON

sys="You are a data extraction engine. You output only strict JSON, matching the provided JSON Schema conceptually."
usr=$(cat <<EOT
Extract data from the following text into a JSON object that fits this schema (field names and types).
Return ONLY valid minified JSON. No comments, no code fences.

Schema:
$SCHEMA

Title: $title

Text:
$text
EOT
)

out=$(ai_chat "$sys" "$usr" | sed 's/```json//g;s/```//g')

# Validate JSON shape is at least valid JSON. Deep schema validation is out of scope here.
echo "$out" | jq -e . >/dev/null 2>&1 || { echo "Model returned invalid JSON:" >&2; printf '%s\n' "$out" >&2; exit 1; }

# Pretty print final JSON
echo "$out" | jq
EOF

chmod +x ~/.local/bin/ai-extract

Usage:

ai-extract README.md "Project README"
cat server.log | ai-extract - "Server Logs"

Real-world examples

  • Drafting commits:

    • After staging: git add -A && ai-commit
    • Paste the result into your editor or pipe through fzf/gum for edits.
  • Troubleshooting:

    • ai-summarize-logs "1 hour ago" 800
    • Quickly spot repeated failures and get hypotheses for next steps.
  • Command generation:

    • ai-cmd "archive all .log files older than 14 days under /var/log into a tar.gz (dry run)"
    • Review the proposed cmd and run with confidence.
  • Data extraction:

    • ai-extract - "Paste an RFC or ticket content to get entities, URLs, and a short summary in JSON."

Tips and safety

  • Secrets: Keep API keys out of shell history. Prefer a keyring, environment injection, or source a gpg-encrypted file.

  • Privacy: For sensitive logs/code, use a local model (Ollama) to avoid network egress.

  • Determinism: Set AI_TEMPERATURE to 0–0.2 for consistent outputs in CI or scripts.

  • Guardrails: For ai-cmd, keep interactive confirmation on. Consider adding a denylist for rm -rf and similar destructive patterns.

  • Versioning: Track your templates in a dotfiles repo and document your prompts alongside team conventions.

Conclusion and next step

You now have a minimal AI layer in Bash plus four practical templates you can evolve:

  • ai-commit for clean commit messages

  • ai-summarize-logs for fast incident triage

  • ai-cmd for safe command synthesis

  • ai-extract for structured data from unstructured text

Next step: wire these into your daily shortcuts. Start with one template, tweak the system prompts for your team’s tone and policies, and point them at either OpenAI or a local Ollama model. If you build a new template, document it and share it with your team—the terminal can be collaborative, too.

Have ideas or want a full repo of these scripts? Tell me what template you want next: code review, doc drafting, ticket triage, or something custom.