- Posted on
- • Artificial Intelligence
Learning Artificial Intelligence Bash
- Author
-
-
- User
- linuxbash
- Posts by this author
- Posts by this author
-
Learning Artificial Intelligence with Bash: Automate AI from the Terminal
If you love living in the terminal, you don’t need notebooks or heavy GUI tools to get real work done with AI. Bash can be your AI command center: reproducible, scriptable, and perfect for automating everyday tasks like summarizing logs, classifying tickets, batch-rewriting documentation, and more.
This post shows why “AI from Bash” is a powerful pattern, then gives you practical, copy‑pasteable snippets to start shipping value today.
Why Bash + AI is a great fit
Glue for everything: Bash orchestrates curl, jq, python, git, and system tools you already use.
Reproducible and auditable: Shell scripts make prompts, parameters, and outputs easy to track in version control.
Fast to automate: Turn one-off commands into cron jobs and CI steps without changing tools.
Portable: Works across servers, containers, and your laptop with minimal dependencies.
Prerequisites: Set up your AI-friendly shell
We’ll use standard CLI tools:
- curl (HTTP), jq (JSON), git (versioning), Python 3 (for local servers and helpers), sqlite3 (optional storage), wget (optional downloads).
Install them with your package manager.
Debian/Ubuntu (apt):
sudo apt update
sudo apt install -y curl jq git python3 python3-venv python3-pip sqlite3 wget
Fedora/RHEL/CentOS (dnf):
sudo dnf install -y curl jq git python3 python3-virtualenv python3-pip sqlite sqlite-devel wget
openSUSE (zypper):
sudo zypper refresh
sudo zypper install -y curl jq git python3 python3-venv python3-pip sqlite3 wget
Tip: Store your API keys securely and load them in your shell session.
mkdir -p ~/.config
cat > ~/.config/ai.env <<'EOF'
# Example: OpenAI-compatible API
export OPENAI_API_KEY="put-your-key-here"
# Optional: Use a custom endpoint that is OpenAI-compatible
# export OPENAI_BASE_URL="https://api.example.com/v1"
EOF
# Load in current shell
source ~/.config/ai.env
# Load automatically in new terminals
grep -q 'source ~/.config/ai.env' ~/.bashrc || echo 'source ~/.config/ai.env' >> ~/.bashrc
Security note: Never commit keys to git. Consider a secrets manager for production.
1) Call an LLM API with curl (no SDK required)
You can talk to any OpenAI-compatible API from pure Bash. That includes many popular providers and local servers that expose the same schema.
Single prompt:
MODEL="gpt-4o-mini" # change to your provider’s model name
BASE="${OPENAI_BASE_URL:-https://api.openai.com/v1}"
curl -sS "$BASE/chat/completions" \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "'"$MODEL"'",
"messages": [{"role":"user","content":"In one sentence, explain Bash arrays."}],
"temperature": 0.3
}' | jq -r '.choices[0].message.content'
Reusable Bash function:
llm() {
local prompt="$1"
local model="${2:-gpt-4o-mini}"
local base="${OPENAI_BASE_URL:-https://api.openai.com/v1}"
curl -sS "$base/chat/completions" \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "'"$model"'",
"messages": [{"role":"user","content":'"$(jq -Rn --arg p "$prompt" '$p')"' }],
"temperature": 0.2
}' | jq -r '.choices[0].message.content'
}
Use it:
llm "Summarize last week's on-call postmortem in 5 bullet points."
Batch over files:
for f in docs/*.md; do
echo "Processing $f"
llm "Rewrite this more concisely while preserving meaning:\n\n$(cat "$f")" > "out/$(basename "$f")"
done
2) Stream outputs for better UX
Streaming gives you tokens as they arrive (great for long answers). Most OpenAI-compatible APIs support SSE.
MODEL="gpt-4o-mini"
BASE="${OPENAI_BASE_URL:-https://api.openai.com/v1}"
curl -N -sS "$BASE/chat/completions" \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "'"$MODEL"'",
"stream": true,
"messages": [{"role":"user","content":"List 5 Linux backup strategies with pros/cons."}],
"temperature": 0.2
}' \
| sed -u 's/^data: //; /"delta":{}/d' \
| jq -r '.choices[0].delta.content // empty'
3) Run a local model server (no Internet, no data leaves your box)
Prefer local inference? The llama.cpp Python server runs entirely on your machine.
Create a venv and install:
python3 -m venv ~/.venvs/llm
~/.venvs/llm/bin/pip install --upgrade pip
~/.venvs/llm/bin/pip install "llama-cpp-python[server]"
Download a GGUF model (example: a small instruct model). Verify license and pick a size your CPU/RAM can handle:
mkdir -p ~/models
cd ~/models
wget https://huggingface.co/TheBloke/TinyLlama-1.1B-Chat-v1.0-GGUF/resolve/main/TinyLlama-1.1B-Chat-v1.0.Q4_K_M.gguf -O tinyllama.gguf
Start the server:
~/.venvs/llm/bin/python -m llama_cpp.server --model ~/models/tinyllama.gguf --host 0.0.0.0 --port 8000
Call it with the same curl shape (OpenAI-compatible):
export OPENAI_BASE_URL="http://127.0.0.1:8000/v1"
unset OPENAI_API_KEY # local server typically doesn’t need a key
curl -sS "$OPENAI_BASE_URL/chat/completions" \
-H "Content-Type: application/json" \
-d '{
"model": "local-llama",
"messages": [{"role":"user","content":"Explain what a Bash here-doc is, with an example."}]
}' | jq -r '.choices[0].message.content'
Tip: For better performance, use models that fit in RAM and support your CPU features. GPU acceleration is possible but outside this short guide.
4) Real-world examples you can run today
A) Summarize yesterday’s logs into a Slack-ready report
YDAY=$(date -d "yesterday" +%F) # or: date -v-1d +%F on BSD/mac
LOG=/var/log/syslog
grep "$YDAY" "$LOG" | tail -n 2000 > /tmp/yesterday.log
SUMMARY=$(llm "Summarize key incidents and recurring warnings in this log. Output bullet points:\n\n$(cat /tmp/yesterday.log)")
printf "*Ops Daily Summary (%s)*\n%s\n" "$YDAY" "$SUMMARY"
B) Classify support tickets (CSV) into categories
input="tickets.csv" # columns: id,subject,body
mkdir -p classified
tail -n +2 "$input" | while IFS=, read -r id subject body; do
prompt="Subject: $subject
Body:
$body
Classify into one of: [Billing, Bug, Feature, How-To]. Respond with only the label."
label=$(llm "$prompt")
echo "$id,$label" >> classified/labels.csv
done
C) Batch-translate Markdown to English, preserve code blocks
mkdir -p translated
for f in content/*.md; do
text=$(cat "$f")
prompt="Translate the following Markdown to English. Preserve code fences and formatting. Do not translate code:\n\n$text"
llm "$prompt" > "translated/$(basename "$f")"
done
D) Programmatic prompt templates with variables
prompt_render() {
local tpl="$1"; shift
# usage: prompt_render template.txt VAR1="value" VAR2="value"
local envs=()
for kv in "$@"; do envs+=(-v "${kv%%=*}=${kv#*=}"); done
awk "${envs[@]}" '{ while (match($0, /\{\{[A-Z0-9_]+\}\}/)) {
key=substr($0, RSTART+2, RLENGTH-4);
gsub("{{"key"}}", ENVIRON[key]);
} print }' "$tpl"
}
export PRODUCT="Backup CLI"
export TONE="friendly and concise"
prompt_render prompt.txt PRODUCT="$PRODUCT" TONE="$TONE" | while read -r chunk; do
: # build prompt if template is multiline; for simplicity, cat the template:
done
llm "$(prompt_render prompt.txt PRODUCT="$PRODUCT" TONE="$TONE")"
Example prompt.txt:
Write a {{TONE}} README introduction for {{PRODUCT}}. Mention Linux support and a one-line install command.
5) Make it reliable: retries, rate limits, and logs
Turn your one-off commands into robust jobs.
request_llm() {
local prompt="$1"
local out="$2"
local tries=0
local max=5
local backoff=2
while (( tries < max )); do
if resp=$(llm "$prompt"); then
printf "%s\n" "$resp" | tee "$out"
return 0
fi
tries=$((tries+1))
sleep $((backoff**tries))
done
echo "ERROR: Failed after $max attempts" >&2
return 1
}
# Example usage
request_llm "Summarize: $(head -c 5000 /var/log/syslog)" out/summary.txt
Schedule with cron:
crontab -e
# Every day at 07:00
0 7 * * * source ~/.config/ai.env && /home/user/bin/daily-log-summary.sh >> /home/user/logs/ai-jobs.log 2>&1
Optional: a tiny local knowledge assistant
Keep notes in Markdown and ask an LLM to answer with citations.
Index file names and top headings:
find notes -name '*.md' -maxdepth 1 -type f -print0 \
| xargs -0 -I{} sh -c 'echo "## {}"; sed -n "1,100p" "{}"' \
> /tmp/notes-heads.txt
Ask a question with open-book context:
QUESTION="How do we deploy our staging environment?"
CONTEXT=$(cat /tmp/notes-heads.txt | head -c 12000)
llm "Using only this context, answer and cite files in parentheses:
Context:
$CONTEXT
Question: $QUESTION
Answer with bullet points and file names in parentheses."
It’s not full RAG, but it’s quick, local, and often good enough.
Troubleshooting tips
JSON errors: Pipe responses to jq to see exact errors.
Long prompts: Many APIs cap tokens. Trim inputs or work in chunks.
Cost control: Log token usage if your provider supports it; sample fewer files.
Speed: Lower temperature, pick smaller models, stream results, or run locally.
Conclusion and next steps
You don’t need to leave the terminal to leverage AI. With curl, jq, and a few small scripts, you can:
Call cloud or local LLMs
Automate summarization, classification, translation
Schedule reliable jobs with retries and logs
Next steps:
Wrap your favorite snippets into a ~/bin toolkit.
Add a Makefile target (e.g., make summarize-logs) for your team.
Experiment with a local model server for private data.
Keep prompts and scripts in git for reproducibility.
If this helped, turn one repetitive task you do weekly into a Bash+AI job today—and enjoy the time you get back.