#!/usr/bin/env bash set -euo pipefail REDIS_HOST="${REDIS_HOST:-127.0.0.1}" REDIS_PORT="${REDIS_PORT:-8888}" REDIS_DB="${REDIS_DB:-0}" REDIS_PASSWORD="${REDIS_PASSWORD:-}" PATTERNS=("ai_chat_service_*") usage() { cat <<'EOF' Usage: inspect_ai_redis.sh [options] Options: --host Redis host, default: 127.0.0.1 --port Redis port, default: 8888 --db Redis db index, default: 0 --password Redis password --pattern Key pattern, can be repeated. Default: ai_chat_service_* --help Show this help Environment: REDIS_HOST REDIS_PORT REDIS_DB REDIS_PASSWORD Examples: ./scripts/inspect_ai_redis.sh ./scripts/inspect_ai_redis.sh --pattern 'ai_chat_service_*' --pattern 'foo_*' REDIS_PORT=6379 ./scripts/inspect_ai_redis.sh --host 10.0.0.8 EOF } while [[ $# -gt 0 ]]; do case "$1" in --host) REDIS_HOST="$2" shift 2 ;; --port) REDIS_PORT="$2" shift 2 ;; --db) REDIS_DB="$2" shift 2 ;; --password) REDIS_PASSWORD="$2" shift 2 ;; --pattern) if [[ "${PATTERNS[*]}" == "ai_chat_service_*" && "${#PATTERNS[@]}" -eq 1 ]]; then PATTERNS=() fi PATTERNS+=("$2") shift 2 ;; --help|-h) usage exit 0 ;; *) echo "Unknown argument: $1" >&2 usage >&2 exit 1 ;; esac done if ! command -v redis-cli >/dev/null 2>&1; then echo "redis-cli not found in PATH" >&2 exit 1 fi redis_cmd() { if [[ -n "$REDIS_PASSWORD" ]]; then redis-cli -h "$REDIS_HOST" -p "$REDIS_PORT" -n "$REDIS_DB" -a "$REDIS_PASSWORD" --raw "$@" else redis-cli -h "$REDIS_HOST" -p "$REDIS_PORT" -n "$REDIS_DB" --raw "$@" fi } print_string() { local key="$1" redis_cmd GET "$key" } print_hash() { local key="$1" redis_cmd HGETALL "$key" | awk 'NR % 2 == 1 { printf "%s: ", $0; next } { print $0 }' } print_list() { local key="$1" redis_cmd LRANGE "$key" 0 -1 } print_set() { local key="$1" redis_cmd SMEMBERS "$key" } print_zset() { local key="$1" redis_cmd ZRANGE "$key" 0 -1 WITHSCORES | awk 'NR % 2 == 1 { printf "%s => ", $0; next } { print $0 }' } print_stream() { local key="$1" redis_cmd XRANGE "$key" - + } if ! redis_cmd PING >/dev/null 2>&1; then echo "Failed to connect to Redis at ${REDIS_HOST}:${REDIS_PORT}, db=${REDIS_DB}" >&2 exit 1 fi declare -A seen_keys=() keys=() for pattern in "${PATTERNS[@]}"; do while IFS= read -r key; do [[ -z "$key" ]] && continue if [[ -z "${seen_keys[$key]:-}" ]]; then seen_keys["$key"]=1 keys+=("$key") fi done < <(redis_cmd --scan --pattern "$pattern") done if [[ "${#keys[@]}" -eq 0 ]]; then echo "No keys matched patterns: ${PATTERNS[*]}" exit 0 fi printf 'Redis: %s:%s db=%s\n' "$REDIS_HOST" "$REDIS_PORT" "$REDIS_DB" printf 'Patterns: %s\n' "${PATTERNS[*]}" printf 'Matched keys: %s\n\n' "${#keys[@]}" for key in "${keys[@]}"; do key_type="$(redis_cmd TYPE "$key" | tr -d '\r')" ttl="$(redis_cmd TTL "$key" | tr -d '\r')" echo "KEY: $key" echo "TYPE: $key_type" echo "TTL: $ttl" echo "VALUE:" case "$key_type" in string) print_string "$key" ;; hash) print_hash "$key" ;; list) print_list "$key" ;; set) print_set "$key" ;; zset) print_zset "$key" ;; stream) print_stream "$key" ;; *) echo "(unsupported type: $key_type)" ;; esac echo done