- Posted on
- • Artificial Intelligence
Your First AI-Powered Bash Script
- Author
-
-
- User
- linuxbash
- Posts by this author
- Posts by this author
-
Your First AI-Powered Bash Script
Ever wished you could ask your terminal to “explain that weird one-liner,” “write a safe Bash snippet,” or “summarize this log file” on the spot? With a tiny Bash script and a single environment variable, you can bolt AI directly onto your command line and supercharge your workflow—no IDE plugins, no heavyweight apps.
In this guide, you’ll build a small, dependable Bash script that:
Talks to an AI model via
curl(cloud-based or local)Explains commands, generates snippets, and summarizes files
Plays nicely with Linux tooling (pipes, redirection, environment variables)
We’ll cover setup, the “why,” and 3–5 practical, real-world examples you can adopt today.
Why put AI in Bash?
It’s where your work happens: You already think and operate in the shell; AI should fit that flow.
Composable: AI output can feed into pipes, files, or other commands.
Lightweight and universal: Works over SSH, inside containers, and on minimal systems.
Auditable: You see every request leaving your machine and can script guardrails.
Prerequisites (install with your package manager)
We’ll use curl to call an API and jq to handle JSON. Install them with your distro’s package manager:
Debian/Ubuntu (apt):
sudo apt update sudo apt install -y curl jqFedora/RHEL/CentOS (dnf):
sudo dnf install -y curl jqopenSUSE (zypper):
sudo zypper refresh sudo zypper install -y curl jq
You’ll also need:
- An API key from an AI provider (for example, OpenAI). Set it as an environment variable:
export OPENAI_API_KEY="sk-...your-key..."Tip: Add this line to your shell profile (e.g.,~/.bashrc) so it’s always available.
Optional (local, no cloud): If you prefer local models, you can use Ollama and skip any cloud keys. Install it using their official instructions, then run:
ollama pull llama3.2
The Script: ai.sh
This script supports two providers:
openai (default, uses
OPENAI_API_KEY)ollama (local, set
PROVIDER=ollama)
It provides helpful subcommands:
ask— freeform questionexplain— explain a shell command safelygen— generate a Bash snippet (aims to be safe and POSIX-friendly)summarize— summarize a text file (limits size)
Create ai.sh:
#!/usr/bin/env bash
set -euo pipefail
# Dependencies: curl, jq
# Provider selection: export PROVIDER=openai (default) or PROVIDER=ollama
PROVIDER="${PROVIDER:-openai}"
# OpenAI config (used when PROVIDER=openai)
MODEL="${MODEL:-gpt-4o-mini}"
ROLE="${ROLE:-You are a helpful Linux and Bash assistant. Prefer concise answers and safe, POSIX-compliant examples. Explain trade-offs and add cautions where relevant.}"
# Ollama config (used when PROVIDER=ollama)
OLLAMA_MODEL="${OLLAMA_MODEL:-llama3.2}"
usage() {
cat <<'USAGE'
Usage:
ai.sh ask "your question"
ai.sh explain "command to explain"
ai.sh gen "describe the Bash you want"
ai.sh summarize /path/to/file
Environment:
PROVIDER=openai|ollama
MODEL=gpt-4o-mini (for OpenAI; override if you wish)
OLLAMA_MODEL=llama3.2 (for Ollama)
OPENAI_API_KEY=... (required for PROVIDER=openai)
Examples:
ai.sh explain "find . -type f -mtime -1 -print0 | xargs -0 tar -czf backup.tgz"
ai.sh gen "rename files by replacing spaces with underscores"
ai.sh ask "What's the safest way to parse CSV in Bash?"
ai.sh summarize /var/log/nginx/access.log
USAGE
}
ensure_tools() {
command -v curl >/dev/null 2>&1 || { echo "curl not found"; exit 1; }
command -v jq >/dev/null 2>&1 || { echo "jq not found"; exit 1; }
}
ask_openai() {
local prompt="$1"
: "${OPENAI_API_KEY:?Set OPENAI_API_KEY for PROVIDER=openai}"
# Build JSON with jq to avoid quoting issues
local payload
payload="$(jq -nc --arg model "$MODEL" --arg role "$ROLE" --arg prompt "$prompt" '{
model: $model,
messages: [
{role: "system", content: $role},
{role: "user", content: $prompt}
],
temperature: 0.2
}')"
curl -fsS https://api.openai.com/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${OPENAI_API_KEY}" \
-d "$payload" \
| jq -r '.choices[0].message.content'
}
ask_ollama() {
local prompt="$1"
# We prepend ROLE to the prompt to provide instruction to the local model
local combined_prompt
combined_prompt="$ROLE
$prompt"
local payload
payload="$(jq -nc --arg model "$OLLAMA_MODEL" --arg prompt "$combined_prompt" '{
model: $model,
prompt: $prompt,
stream: false
}')"
curl -fsS http://localhost:11434/api/generate \
-H "Content-Type: application/json" \
-d "$payload" \
| jq -r '.response'
}
ask_ai() {
local prompt="$1"
if [[ "$PROVIDER" == "ollama" ]]; then
ask_ollama "$prompt"
else
ask_openai "$prompt"
fi
}
explain_command() {
local cmd="$1"
ask_ai "Explain the following shell command step by step, including what each flag does. Add safety notes and potential pitfalls. Command:
$cmd"
}
gen_bash() {
local task="$1"
ask_ai "Write a safe, POSIX-compliant Bash snippet to accomplish the following. Explain assumptions and include set -euo pipefail and comments. Task:
$task"
}
summarize_file() {
local file="$1"
[[ -r "$file" ]] || { echo "File not readable: $file" >&2; exit 1; }
# Limit content to avoid sending large/secret data unintentionally
# You can tune the limit; here we use 50KB.
local limit=51200
local content
content="$(head -c "$limit" -- "$file")"
ask_ai "Summarize the following file content in bullet points. If it looks like logs, extract key trends, errors, and counts. If it's code, summarize structure and responsibilities. Truncated to ${limit} bytes:
$content"
}
main() {
ensure_tools
local subcmd="${1:-}"
shift || true
case "$subcmd" in
ask)
[[ $# -gt 0 ]] || { usage; exit 1; }
ask_ai "$*"
;;
explain)
[[ $# -gt 0 ]] || { usage; exit 1; }
explain_command "$*"
;;
gen)
[[ $# -gt 0 ]] || { usage; exit 1; }
gen_bash "$*"
;;
summarize)
[[ $# -eq 1 ]] || { usage; exit 1; }
summarize_file "$1"
;;
*)
usage
exit 1
;;
esac
}
main "$@"
Make it executable:
chmod +x ai.sh
Provider selection:
Cloud (default):
export OPENAI_API_KEY=...and run./ai.sh ...Local (Ollama):
export PROVIDER=ollamaand run./ai.sh ...(make sureollama serveis running and you’ve pulled a model)
4 Real-World Things You Can Do Immediately
1) Explain scary one-liners before you run them
./ai.sh explain "find . -type f -mtime -1 -print0 | xargs -0 tar -czf backup.tgz"
- You’ll get a breakdown of each flag, what the pipeline does, and safety notes (e.g.,
-print0and-0to avoid issues with spaces/newlines).
2) Generate safe Bash for common tasks
./ai.sh gen "rename files by replacing spaces with underscores in the current directory"
- Expect a snippet with
set -euo pipefail, comments, and a careful loop usingfind -print0andwhile IFS= read -r -d ''.
3) Summarize logs or configs quickly
./ai.sh summarize /var/log/nginx/access.log
- Useful for spotting spikes, common status codes, or IPs. The script trims large files to 50KB by default; raise the limit if you need more context.
4) Ask for safer patterns or alternatives
./ai.sh ask "Is parsing JSON with grep safe? What's a safer alternative in Bash?"
- This nudges you toward best practices (e.g., using
jqinstead of brittle text parsing).
Bonus: Pipe and redirect like any other tool
./ai.sh gen "one-liner to list largest 10 files under /var with sizes" | tee largest-files.sh
bash largest-files.sh
Tips, Safety, and Customization
Don’t paste secrets: Avoid sending credentials, tokens, private data, or sensitive logs. Consider redacting/sanitizing first.
Set usage limits: For large files, increase/decrease the
limitinsummarize_file.Swap models: Try faster/cheaper or more capable models by changing
MODEL(OpenAI) orOLLAMA_MODEL(local).MODEL=gpt-4o-mini ./ai.sh ask "How do I parse INI files in Bash?" OLLAMA_MODEL=llama3.2 ./ai.sh ask "Show a POSIX-safe way to create temp files"Version control your prompts: Tune the
ROLEtext to define the assistant’s style and guardrails for your team.Handle costs and quotas: Cloud APIs may be billable. Add caching or store results if you repeat queries.
CI/CD and servers: Works over SSH and in containers; just bring
curl,jq, and the right environment variables.
Troubleshooting
401/403 errors: Check
OPENAI_API_KEYand your account permissions.Connection refused (Ollama): Ensure the service is running (
ollama serve) and that you’ve pulled a model.Missing tools: Install with your package manager:
- apt:
sudo apt update && sudo apt install -y curl jq- dnf:
sudo dnf install -y curl jq- zypper:
sudo zypper refresh && sudo zypper install -y curl jq
Conclusion and Next Steps
You’ve just wired AI into your terminal with a single script. From here:
Extend
ai.shwith project-aware context (e.g., includegit difforREADME.mdautomatically).Add a
lintsubcommand that asks AI to review a script for portability and pitfalls.Wrap frequent prompts in aliases or functions (e.g.,
alias aiex='ai.sh explain').
Call to Action:
Drop this script into your dotfiles repo and share it with your team.
Try it on your trickiest one-liner today—and never run a mystery command again.