GC-301g · Module 3
Shell Script Integration
3 min read
Shell scripts are the natural home for Gemini CLI automation. Bash provides variable expansion, conditionals, loops, pipes, redirects, and error handling — everything you need to build multi-step AI workflows. The pattern: define a function that wraps gemini -p with error handling and output validation, then call that function from your workflow logic. Separation of the Gemini invocation from the workflow logic makes scripts testable, debuggable, and maintainable.
Production shell scripts need defensive coding. Set -euo pipefail at the top to fail on any error, undefined variable, or pipe failure. Trap EXIT to clean up temporary files. Quote all variable expansions to handle filenames with spaces. Log every Gemini invocation with timestamp, input size, exit code, and output size for post-mortem debugging. These are not optional niceties — they are the difference between a script that works on your machine and one that works in production.
#!/bin/bash
set -euo pipefail
trap 'rm -f "$TMPFILE"' EXIT
LOGFILE="gemini-automation.log"
TMPFILE=$(mktemp)
log() { echo "[$(date -Iseconds)] $*" >> "$LOGFILE"; }
gemini_safe() {
local prompt="$1"
local label="${2:-unnamed}"
local start=$(date +%s)
log "START $label (prompt: ${#prompt} chars)"
if ! gemini -p "$prompt" --output-format json > "$TMPFILE" 2>/dev/null; then
log "FAIL $label (exit: $?)"
return 1
fi
if ! jq empty "$TMPFILE" 2>/dev/null; then
log "FAIL $label (invalid JSON)"
return 1
fi
local elapsed=$(( $(date +%s) - start ))
log "OK $label (${elapsed}s, $(wc -c < "$TMPFILE") bytes)"
cat "$TMPFILE"
}
# Usage in a workflow
result=$(gemini_safe "Analyze the test coverage gaps in src/" "coverage-analysis")
if [ $? -eq 0 ]; then
echo "$result" | jq '.response' > reports/coverage-gaps.md
log "Report written to reports/coverage-gaps.md"
fi