- 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.