- Posted on
- • Artificial Intelligence
Artificial Intelligence Bash Prompt Engineering
- Author
-
-
- User
- linuxbash
- Posts by this author
- Posts by this author
-
Artificial Intelligence Bash Prompt Engineering
Bring an AI sidekick into your terminal—without leaving Bash. If you’ve ever lost flow by tabbing to a browser for “that awk one‑liner” or digging through a manpage rabbit hole, you already know the cost of context switching. With a bit of prompt engineering and a few shell helpers, you can query an LLM, get safe, concise answers, and even wire key bindings to explain or generate commands on the fly—all from Bash.
This post shows you how to:
Install minimal tools
Craft reliable prompts that work well in CLI workflows
Create an
aifunction usingcurlandjqAdd AI helpers that explain commands, propose safe one‑liners, and slot into your readline workflow
The value: faster problem solving, fewer mistakes, and reproducible, scriptable AI interactions that live inside your dotfiles.
Why “AI + Bash” is a perfect fit
Text is the API. Bash speaks plain text; LLMs speak plain text. There’s no impedance mismatch.
Reproducibility. Prompt templates in dotfiles are auditable, versionable, and easy to share.
Guardrails by default. You decide what context to send, how to format answers, when to run anything (never auto‑eval).
Composability. Pipe AI output through
grep,fzf, orlessand keep the Unix philosophy intact.
Prerequisites (install once)
We’ll use curl to call the API, jq to parse JSON, and optionally fzf and bash-completion for nicer CLI ergonomics.
- Debian/Ubuntu (apt):
sudo apt update
sudo apt install -y curl jq fzf bash-completion
- Fedora/RHEL/CentOS Stream (dnf):
sudo dnf install -y curl jq fzf bash-completion
- openSUSE (zypper):
sudo zypper refresh
sudo zypper install -y curl jq fzf bash-completion
You’ll also need an API endpoint and key. For example, with OpenAI:
export OPENAI_API_KEY="sk-..."
export AI_BASE_URL="https://api.openai.com"
export AI_MODEL="gpt-4o-mini"
Or any OpenAI‑compatible endpoint—just set AI_BASE_URL, OPENAI_API_KEY, and AI_MODEL.
Tip: add those exports to your ~/.bashrc or a dedicated ~/.bash_ai and source it.
Step 1: Create a robust ai function with a safe, structured prompt
Put this in ~/.bash_ai and source ~/.bash_ai from your ~/.bashrc.
# ~/.bash_ai
# Configuration (override in your shell as needed)
export AI_BASE_URL="${AI_BASE_URL:-https://api.openai.com}"
export AI_MODEL="${AI_MODEL:-gpt-4o-mini}"
# Core system prompt: role + constraints = fewer hallucinations
AI_SYSTEM_PROMPT=${AI_SYSTEM_PROMPT:-$'You are a senior Linux/Bash assistant.\n\
- Be precise and concise.\n\
- Prefer POSIX-friendly commands unless GNU features are needed.\n\
- If unsure, ask 1–2 clarifying questions first.\n\
- If asked for a command, output only the command in a single fenced code block.\n\
- Warn about destructive flags (e.g., rm -rf) and suggest safer alternatives.\n\
- Cite man pages/flags briefly when helpful.\n\
'}
# Internal helper: send a chat completion request and return content
__ai_request() {
local role_sys="${1:?system prompt required}"
local user_msg="${2:?user message required}"
local temperature="${3:-0.2}"
local api_key="${OPENAI_API_KEY:?Set OPENAI_API_KEY (export OPENAI_API_KEY=...)}"
jq -n --arg sys "$role_sys" --arg user "$user_msg" --argjson temp "$temperature" '
{
model: env.AI_MODEL,
temperature: $temp,
messages: [
{role: "system", content: $sys},
{role: "user", content: $user}
]
}' |
curl -sS "$AI_BASE_URL/v1/chat/completions" \
-H "Authorization: Bearer '"$api_key"'" \
-H "Content-Type: application/json" \
-d @- |
jq -r '.choices[0].message.content'
}
# Public: free-form assistant
ai() {
local ctx="OS: $(uname -a)
Shell: $BASH --version | head -1
PWD: $PWD"
local prompt="$*"
# Include thin, relevant context without oversharing
__ai_request "$AI_SYSTEM_PROMPT" "Context:\n$ctx\n\nTask:\n$prompt" 0.2
}
# Public: explain a command safely
ai-explain() {
local cmd="$*"
local p=$'Explain what this command does, step by step. Include:\n\
- Purpose of each flag\n\
- Potential risks & safer alternatives\n\
- Example input/output (short)\n\
Command:\n'"$cmd"
__ai_request "$AI_SYSTEM_PROMPT" "$p" 0.0 | less -R
}
# Public: request a single safe command (no prose)
ai-cmd() {
local task="$*"
local p=$'Return only ONE shell command inside a single fenced code block.\n\
Constraints:\n\
- Assume GNU userland unless specified.\n\
- Avoid destructive operations; if truly needed, use -n/--dry-run or echo preview first.\n\
- Use absolute flags and be explicit.\n\
Task:\n'"$task"
# Print the command block verbatim; user decides to run or not
__ai_request "$AI_SYSTEM_PROMPT" "$p" 0.1
}
# Optional: strip code fences to extract the raw command
ai-cmd-raw() {
ai-cmd "$*" | awk '
BEGIN{inblk=0}
/^```/{inblk=!inblk; next}
inblk{print}
'
}
# Optional readline binding: press Ctrl-g to explain what you’re typing
__ai_ask_buffer() {
local line="$READLINE_LINE"
if [[ -z "$line" ]]; then
echo "[ai] Nothing on the command line."
return
fi
echo "[ai] Explaining: $line"
ai-explain "$line"
}
# Bind Ctrl-g (press Control+g in Bash line editor)
bind -x '"\C-g":"__ai_ask_buffer"'
Reload:
source ~/.bash_ai
Now try:
ai "Show me how to recursively find files > 2 GiB under the current directory and display sizes in a human-readable, descending list."
Step 2: Prompt engineering patterns that work in the CLI
Role + constraints
- Tell the model what it is (“senior Linux/Bash assistant”) and what not to do (no destructive defaults, be concise).
Minimal, relevant context
- Provide OS, shell, and directory; avoid dumping huge logs unless necessary.
Output contracts
- For commands, force a single fenced code block. For explanations, ask for bullets and flag annotations.
Ask before risk
- Encourage the model to ask 1–2 clarifying questions if ambiguity could lead to danger.
Determinism first
- Use low temperature (0.0–0.2) for commands; it reduces creative drift.
Step 3: Real‑world examples you can use today
1) Explain a pipeline before you run it
ai-explain "grep -RIlZ 'password' . | xargs -0 sed -i 's/password/SECRET/g'"
2) Generate a safe, dry‑run refactor
ai-cmd "Rename all *.jpeg to *.jpg recursively from \$PWD. Use a dry-run first, then show the actual command."
Then extract the raw command if you want to copy/paste:
ai-cmd-raw "Rename all *.jpeg to *.jpg recursively from \$PWD. Use a dry-run first, then show the actual command."
3) Build data one‑liners with guardrails
ai "Write an awk one-liner to sum the 5th column of a CSV if the 7th column equals OK. Assume commas, header row present, and ignore malformed lines. Include a short example."
4) Summarize log snippets
journalctl -u nginx --since "2 hours ago" | tail -n 400 | \
awk 'NR==1, NR==400' | \
ai "Summarize key errors and likely root causes in <=5 bullets. If config hints are needed, cite the directive names only."
5) Ask the AI about what you’re typing (Ctrl‑g)
Start typing a command, e.g.
rsync -av --delete src/ dst/Press Ctrl‑g to open an annotated explanation in
less.
Step 4: Safety and ergonomics you shouldn’t skip
Never auto‑execute AI output
- Keep the “show, don’t run” default. If you do add a runner, prompt for explicit confirmation and show the command first.
Prefer dry‑runs
- Ask for
--dry-run,-n, or echo/preview steps for anything that modifies files.
- Ask for
Sanitize large context
- Don’t paste secrets, tokens, or entire configs unless you must. Keep the “Context” block small.
Cost/latency
- Use smaller, cheaper models for routine tasks; reserve larger models for deep troubleshooting.
Auditability
- Commit
~/.bash_aito a private dotfiles repo. Prompts are part of your tooling, so treat them like code.
- Commit
Optional: Fuzzy pick an answer with fzf
If you like interactive flows, pipe multi‑option outputs to fzf and then copy the selection.
ai "Propose 3 different ways to extract unique IPs from access.log; each in one fenced code block." | fzf
Troubleshooting
HTTP 401 or similar
- Ensure
OPENAI_API_KEYis exported and valid, andAI_BASE_URLpoints to the correct endpoint.
- Ensure
Empty output
- Check
jqandcurlare installed (see install commands above).
- Check
Slow responses
- Lower the context you pass, use a lighter model, or increase your terminal’s scrollback and read via
less -R.
- Lower the context you pass, use a lighter model, or increase your terminal’s scrollback and read via
Conclusion and next steps
AI in the terminal works best when you engineer the conversation: set a role, constrain the output, and confirm before you run anything. You now have:
A reusable
aifunction with sane defaultsai-explainandai-cmdhelpers for everyday tasksA readline key binding for instant, in‑context help
Call to action:
Drop the snippet in
~/.bash_ai, source it from~/.bashrc, and try the examples.Iterate on the
AI_SYSTEM_PROMPTto fit your team’s standards.Share your dotfiles and patterns—prompt engineering is a craft, and Bash is the perfect workbench.