- Posted on
- • Artificial Intelligence
Artificial Intelligence for Ubuntu Administrators
- Author
-
-
- User
- linuxbash
- Posts by this author
- Posts by this author
-
Artificial Intelligence for Ubuntu Administrators: Practical CLI Workflows You Can Trust
You’re on-call. It’s 02:13. SSH login failures spike, a disk is creeping toward 100%, and a noisy alert floods your inbox. You don’t want a chatbot—you want a calm, fast, local assistant that helps you decide what to do next and produces safe, reviewable commands. This guide shows Ubuntu administrators how to bring AI right into the terminal using open-source tools, keeping data on your servers and under your control.
What you’ll get:
A minimal, local AI setup you can run on Ubuntu (and commands for apt, dnf, and zypper where relevant)
Reproducible, CLI-first workflows for triage, diagnostics, and automation
3–5 concrete, copy-paste-able examples you can adapt to your environment
Note: Although this is written for Ubuntu admins, install instructions for apt, dnf, and zypper are included to help you support mixed fleets.
Why AI belongs in an Ubuntu admin’s toolbox
Reduce MTTR: Quickly summarize logs and isolate patterns an exhausted brain might miss under pressure.
Safer automation: Generate Bash or Ansible snippets with guardrails, then review before execution.
Keep data local: Use a local model runtime so sensitive logs and infra details never leave your server.
Work at terminal speed: Pipe outputs into an LLM, get structured answers back, and keep moving.
What we’ll build
A local LLM runtime (Ollama) for on-device text generation, plus a thin Bash wrapper
Lightweight CLI helpers: jq, ripgrep, fzf, parallel
Four actionable workflows: 1) Summarize and triage logs 2) Generate safe Bash one-liners 3) Draft Ansible tasks from shell steps 4) Classify/dedupe alerts 5) (Optional) Quick capacity check with sysstat
1) Install prerequisites
Install core CLI tools:
curl: fetch data over HTTP
jq: parse JSON
ripgrep (rg): fast grep for logs
fzf: fuzzy finder (handy but optional)
parallel: parallelize shell pipelines
sysstat (optional): vmstat/iostat/sar tools for quick capacity checks
Using apt (Ubuntu/Debian):
sudo apt update
sudo apt install -y curl jq ripgrep fzf parallel sysstat
Using dnf (Fedora/RHEL family):
sudo dnf install -y curl jq ripgrep fzf parallel sysstat
Using zypper (openSUSE/SLES):
sudo zypper refresh
sudo zypper install -y curl jq ripgrep fzf parallel sysstat
Install a local LLM runtime (Ollama):
curl -fsSL https://ollama.com/install.sh | sh
sudo systemctl enable --now ollama
Pull a small, capable model (choose one you prefer):
ollama pull llama3
# or
ollama pull mistral
Smoke test:
ollama run llama3 "In one sentence, explain what a Linux process is."
If you run this on a busy or small VM, start with smaller models and stop the service when not needed:
sudo systemctl stop ollama
2) Add a tiny Bash helper for local LLM calls
Create a couple of helper functions that:
Send prompts to your local model via Ollama’s HTTP API
Return only the generated text (no streaming noise)
Optionally extract code blocks (bash, YAML) from the answer
Append this to your ~/.bashrc (or source it in your shell profile):
# Default model can be overridden per-shell: export OLLAMA_MODEL=mistral
export OLLAMA_MODEL="${OLLAMA_MODEL:-llama3}"
# Extract content from the first fenced code block
strip_fences() {
awk 'BEGIN{inb=0} /```/{inb=!inb; next} inb{print}'
}
# Core LLM call (non-streaming) using Ollama's API
llm() {
local prompt="$*"
curl -s http://localhost:11434/api/generate \
-d "$(jq -n --arg m "$OLLAMA_MODEL" --arg p "$prompt" --argjson s false '{model:$m, prompt:$p, stream:$s}')" \
| jq -r '.response'
}
# Ask for a fenced bash block and return only the code
llm_bash() {
local prompt="$*"
llm "You are a cautious Linux SRE. Return ONLY one fenced bash code block that solves: $prompt" | strip_fences
}
# Ask for a fenced YAML block and return only the YAML
llm_yaml() {
local prompt="$*"
llm "Return ONLY one fenced YAML code block. $prompt" | strip_fences
}
# Quick test
# llm "In one bullet list, name 3 safe ways to check disk usage on Ubuntu."
Reload your shell:
source ~/.bashrc
3) Actionable workflow: Summarize and triage SSH/auth logs
Triage repeated failures faster by letting the model summarize patterns and propose next steps you can review.
Systemd-based logs (recent 2 hours):
journalctl -u ssh.service --since "2 hours ago" \
| rg '(Failed|Invalid|authentication failure)' \
| tail -n 500 \
| llm "Summarize these SSH auth failures: list the top offending IPs with counts, common usernames targeted, and propose two safe next steps. Keep it short."
Traditional auth.log:
sudo rg '(Failed|Invalid|authentication failure)' /var/log/auth.log \
| tail -n 500 \
| llm "Summarize these SSH auth failures: top offending IPs and usernames, and safe mitigation steps. Short bullets."
Want model-suggested firewall rules? Keep them separate so you can review:
journalctl -u ssh.service -S "6 hours ago" \
| rg 'Failed password' \
| awk '{print $(NF-3)}' \
| sort | uniq -c | sort -nr | head -n 5 \
| llm_bash "Given these 'count IP' lines, produce nftables commands to DROP only the worst 3 IPs, ensure idempotence, and include comments. Do not modify SSH port or unrelated rules."
Review carefully before running anything. If you decide to apply:
# Example: preview
llm_bash "..." | tee /tmp/nft-block.sh
# After manual review:
sudo bash /tmp/nft-block.sh
Guardrails:
Always preview generated commands (tee or less) before execution.
Keep prompts specific: idempotence, scope, and rollback notes.
4) Actionable workflow: Generate safe Bash from plain-English tasks
Turn “what you want” into a vetted one-liner (or small script), then inspect.
Example: find and delete core dumps older than 14 days under /var, but preview first.
llm_bash "Find core dump files under /var larger than 100M and older than 14 days. First show a preview with size and path, then provide a separate command to delete them safely."
You can also ask for guardrails explicitly:
llm_bash "Rotate logs in /opt/myapp/logs when exceeding 500MB, compress old logs with zstd, and keep last 14. Use set -euo pipefail, and do not delete active logs."
Tip: If the answer is too long or includes commentary, the strip_fences helper ensures you only get the code block.
5) Actionable workflow: Draft Ansible tasks from shell steps
Convert a manual playbook-in-your-head into Ansible YAML. This reduces drift and shares knowledge with teammates.
Example: install and enable nginx, manage a config file, and ensure service restarts on change.
llm_yaml "Write an Ansible task list to:
- install nginx on Ubuntu using apt with cache update
- deploy /etc/nginx/sites-available/example with a handler to reload on change
- enable and start nginx
Use idempotent patterns and notify handlers appropriately."
Save and test:
llm_yaml "..." | tee tasks/nginx.yml
ansible-playbook -i inventory site.yml --syntax-check
You can also ask the model to convert shell snippets into Ansible equivalents:
llm_yaml "Convert these steps to Ansible tasks:
1) apt-get update && apt-get install -y fail2ban
2) copy a jail.local with SSH jail enabled
3) enable and start fail2ban
Return only YAML tasks and handlers."
6) Actionable workflow: Classify and de-duplicate noisy alerts
Group similar errors to cut noise and focus on what matters.
Grab recent high-priority logs and let the model cluster themes:
journalctl -p err -S "24 hours ago" -o short-iso \
| head -n 800 \
| llm "Group these log lines into at most 6 problem categories with counts. For each category, provide one likely root cause and one immediate diagnostic step. Keep it concise."
Or extract top offenders first, then ask for recommendations:
journalctl -p err -S "24 hours ago" \
| rg -o '^[^:]+: [^:]+: (.*)$' -r '$1' \
| sed 's/\[[^]]*\]//g' \
| sort | uniq -c | sort -nr | head -n 15 \
| llm "For each line (count message), explain probable cause and one command to validate. Keep answers short."
7) (Optional) Quick capacity and trend check with sysstat
You don’t need historical archives to get value. Pull a short sample and ask the model to summarize.
Sampling:
# CPU/memory/process run queue snapshot
vmstat 1 5 > /tmp/vmstat.txt
# Disk IO snapshot
iostat -xz 1 5 > /tmp/iostat.txt 2>/dev/null || true
# Filesystems
df -hT > /tmp/df.txt
Summarize:
cat /tmp/vmstat.txt /tmp/iostat.txt /tmp/df.txt \
| llm "Summarize performance: are CPUs saturated, IO wait elevated, or any filesystems near capacity? Bullet list with suggested next checks (commands) only."
If you want historical data, enable sysstat collection later, but snapshots are often enough for triage.
Tips for reliability and safety
Be explicit in prompts: idempotence, scope, distro, and rollback details.
Keep sensitive data local: running Ollama on the host ensures logs and commands don’t leave your environment.
Review before running: always capture generated commands to a file and read them.
Resource use: local models consume CPU/RAM (and GPU if available). Stop when not needed:
sudo systemctl stop ollama
Troubleshooting
Ollama service:
systemctl status ollama journalctl -u ollama -bChange model:
export OLLAMA_MODEL=mistralModel too slow or verbose? Ask for fewer bullets, or switch to a smaller model.
Conclusion and next steps
You don’t need a cloud subscription or a GUI to get real, on-call value from AI. With a local model and a few Bash helpers, you can:
Summarize messy logs
Generate safe Bash or Ansible
Cut alert noise
Speed triage and decision-making
Your next step: 1) Install the prerequisites and Ollama. 2) Drop the llm/llm_bash/llm_yaml helpers into your shell. 3) Try the SSH triage and capacity check recipes on a non-production box. 4) Build a small, living runbook.md with your best prompts and pipelines.
When you’re ready, share these helpers across your team and standardize on a known-good model so everyone gets consistent, local, private AI assistance—right from the terminal.