- Posted on
- • Artificial Intelligence
Building an Artificial Intelligence Linux Command Assistant
- Author
-
-
- User
- linuxbash
- Posts by this author
- Posts by this author
-
Building an AI Linux Command Assistant (in pure Bash)
Ever stared at a blinking cursor thinking “there has to be a one-liner for this…”? Imagine a shell companion that:
Translates natural language into precise Bash commands
Explains cryptic errors and logs
Offers safe “confirm before run” execution
Avoids catastrophic footguns by default
In this guide, you’ll build exactly that: a small Bash tool that talks to an LLM (cloud or local) and becomes your on-demand Linux command assistant.
Why this matters:
LLMs are great at transforming intent into shell incantations.
A thin Bash wrapper gives you reproducibility, auditability, and control (prompts, guardrails, dry-runs).
You keep your workflow in the terminal you already love.
What you’ll build
A single ai CLI with subcommands:
ai chat "…". Ask questions in natural language.ai cmd "…". Get only the final Bash command (no prose).ai run "…". Get a command, then confirm to execute it.ai explain. Pipe output/logs and get a human-readable diagnosis.ai fix <failing command …>. Run a command, capture the failure, and get a suggested fix.
Backends supported:
OpenAI (cloud) via API
Ollama (local) for private, offline-ish usage
Prerequisites and installation
1) Install required packages (curl and jq)
- Debian/Ubuntu (apt):
sudo apt update
sudo apt install -y curl jq ca-certificates
- Fedora/RHEL/CentOS (dnf):
sudo dnf install -y curl jq ca-certificates
- openSUSE (zypper):
sudo zypper install -y curl jq ca-certificates
2) Pick an AI backend
Option A — Cloud (OpenAI)
Get an API key from your OpenAI account.
Export environment variables (add these to ~/.bashrc to persist):
export AI_PROVIDER=openai
export OPENAI_API_KEY="sk-...your-key..."
# Pick a model name you have access to, e.g. gpt-4o or gpt-4o-mini
export AI_MODEL="gpt-4o-mini"
Option B — Local (Ollama)
- Install Ollama:
curl -fsSL https://ollama.com/install.sh | sh
- Start the service if needed:
sudo systemctl enable --now ollama
- Pull a model (example: Llama 3, 8B):
ollama pull llama3:8b
- Export environment variables:
export AI_PROVIDER=ollama
export AI_MODEL="llama3:8b"
3) Install the ai script
mkdir -p ~/.local/bin
nano ~/.local/bin/ai
Paste the script below, save, then:
chmod +x ~/.local/bin/ai
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc
The assistant script
Paste this whole script into ~/.local/bin/ai:
#!/usr/bin/env bash
set -euo pipefail
# Configuration (override via environment)
: "${AI_PROVIDER:=openai}" # openai | ollama
: "${AI_MODEL:=gpt-4o-mini}" # For openai; use something like llama3:8b for ollama
: "${AI_TEMPERATURE:=0.2}"
SYSTEM_PROMPT_DEFAULT=$'You are a careful Linux shell assistant for experienced users.\n\
When asked for commands, reply with a minimal, safe, POSIX-compliant Bash one-liner first in a fenced code block, then a brief explanation.\n\
Never claim to have executed anything.\n\
If a command can be destructive (rm, dd, chmod -R, mkfs, chown -R, etc.), add a clear CAUTION and provide a dry-run or safer alternative.'
SYSTEM_PROMPT="${SYSTEM_PROMPT:-$SYSTEM_PROMPT_DEFAULT}"
# --- Backend adapters --------------------------------------------------------
_ai_call_openai() {
local prompt=$1
if [[ -z "${OPENAI_API_KEY:-}" ]]; then
echo "ERROR: OPENAI_API_KEY is not set" >&2
return 2
fi
# Build JSON and call OpenAI Chat Completions
jq -n \
--arg model "$AI_MODEL" \
--arg sys "$SYSTEM_PROMPT" \
--arg user "$prompt" \
--argjson temp "$(printf '%s' "$AI_TEMPERATURE" | jq -R 'tonumber? // 0.2')" \
'{
model: $model,
temperature: $temp,
messages: [
{role:"system", content:$sys},
{role:"user", content:$user}
]
}' \
| curl -fsS https://api.openai.com/v1/chat/completions \
-H "Authorization: Bearer ${OPENAI_API_KEY}" \
-H "Content-Type: application/json" \
-d @- \
| jq -r '.choices[0].message.content // empty'
}
_ai_call_ollama() {
local prompt=$1
local model="${AI_MODEL:-llama3:8b}"
local full_prompt="You are a Linux shell assistant.
$SYSTEM_PROMPT
User:
$prompt
Assistant:"
jq -n \
--arg model "$model" \
--arg prompt "$full_prompt" \
--argjson temp "$(printf '%s' "$AI_TEMPERATURE" | jq -R 'tonumber? // 0.2')" \
'{model:$model, prompt:$prompt, stream:false, options:{temperature:$temp}}' \
| curl -fsS http://localhost:11434/api/generate \
-H "Content-Type: application/json" \
-d @- \
| jq -r '.response // empty'
}
_ai_call() {
local prompt=$1
case "$AI_PROVIDER" in
openai) _ai_call_openai "$prompt" ;;
ollama) _ai_call_ollama "$prompt" ;;
*) echo "ERROR: Unsupported AI_PROVIDER: $AI_PROVIDER" >&2; return 2 ;;
esac
}
# --- Public commands ---------------------------------------------------------
cmd_only_prompt() {
# Tight prompt to force a single command, no noise.
printf 'Output ONLY the final Bash command, with no backticks, no code fences, no comments, no explanations.\nTask: %s\n' "$1"
}
ai_chat() {
local prompt
if [ -t 0 ]; then
prompt="$*"
else
prompt="$(cat)"
[ -n "${*:-}" ] && prompt="${prompt}"$'\n'"$*"
fi
_ai_call "$prompt"
}
ai_cmd() {
local prompt
prompt="$(cmd_only_prompt "$*")"
_ai_call "$prompt" | sed -e 's/^```.*$//' -e 's/^$//'
}
ai_run() {
local cmd
cmd="$(ai_cmd "$*")" || return
if [[ -z "$cmd" ]]; then
echo "No command returned." >&2
return 1
fi
echo "Candidate command:"
echo "$cmd"
read -r -p "Run this command? [y/N] " ans
if [[ "${ans,,}" == "y" ]]; then
bash -c "$cmd"
else
echo "Aborted."
return 1
fi
}
ai_explain() {
local input
input="$(cat)"
_ai_call "Explain the following Linux output/error like a senior sysadmin would, then propose a minimal, safe fix:\n\n$input"
}
ai_fix() {
if [[ $# -eq 0 ]]; then
echo "Usage: ai fix <failing command and args...>" >&2
return 2
fi
set +e
local output rc
output="$("$@" 2>&1)"; rc=$?
set -e
if (( rc == 0 )); then
echo "Command succeeded (exit $rc). Nothing to fix."
return 0
fi
_ai_call "This command failed with exit code $rc. Diagnose and propose a corrected command ONLY (first), then a brief reason.\n\nCommand:\n$*\n\nOutput:\n$output"
}
# --- CLI dispatch ------------------------------------------------------------
sub="${1:-chat}"; shift || true
case "$sub" in
chat) ai_chat "$@" ;;
cmd) ai_cmd "$@" ;;
run) ai_run "$@" ;;
explain) ai_explain ;;
fix) ai_fix "$@" ;;
*) echo "Usage: ai [chat|cmd|run|explain|fix] [...]; see source for details." >&2; exit 2 ;;
esac
Notes:
The script defaults to OpenAI. Set AI_PROVIDER and AI_MODEL to switch.
All dangerous operations are discouraged by the system prompt, but you remain in control (especially via
ai run).
How to use it (real-world examples)
- Translate intent to command (preview safely)
ai chat "Recursively find files over 1G in /var but ignore /var/log"
- Get just the command (no prose)
ai cmd "Recursively convert .jpeg to .jpg in current directory"
- Confirm and run
ai run "Create a gzipped tar of ~/projects excluding node_modules and .git"
- Explain weird output
dmesg | tail -n 200 | ai explain
- Fix a failure
ai fix ls /root
Tips:
If the assistant proposes something destructive, it should also propose a dry-run. Prefer
ai runso you can confirm.Adjust temperature for more/less creativity:
export AI_TEMPERATURE=0.1
- Tighten or customize behavior via SYSTEM_PROMPT:
export SYSTEM_PROMPT="Always return POSIX sh-compatible commands; prefer grep+awk+sed; never use sudo."
Why this pattern works
Minimal dependencies (curl + jq) keep the tool portable.
Backend-agnostic design lets you switch between cloud and local models.
“Command-only” mode and “confirm-to-run” mode separate generation from execution.
Explicit guardrails in the system prompt reduce risky output.
Each subcommand composes cleanly with Unix pipes.
Hardening ideas
Log all accepted commands to a local audit file.
Inject context from your machine (e.g.,
uname -a, distro,$SHELL) into the prompt when it helps.Add a “dry-run” injection for known footguns automatically.
Run
shellcheckon AI-generated scripts before execution.Never run
ai runas root unless absolutely necessary.
Conclusion and next steps
You’ve built a practical AI command assistant that stays in Bash, respects your workflow, and helps you move faster without sacrificing safety.
Where to go from here:
Wire this into your dotfiles and share with your team.
Add a subcommand that summarizes
manpages or TLDR entries.Cache frequent answers in
~/.cache/ai/.Extend the provider to support other OpenAI-compatible endpoints.
Your terminal just got smarter—now put it to work on your next task.