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 -b
    
  • Change model:

    export OLLAMA_MODEL=mistral
    
  • Model 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.