#!/usr/bin/env bash # zzz - Sleep timer with notification # Usage: zzz -s 5 (5 seconds) # zzz -m 2 (2 minutes) # zzz 30 (30 seconds, default unit) # zzz -q -s 10 (quiet - no voice, just ding) set -euo pipefail QUIET=false SECONDS_TOTAL=0 usage() { echo "Usage: zzz [-s seconds] [-m minutes] [-q] [seconds]" echo " -s SEC Sleep for SEC seconds" echo " -m MIN Sleep for MIN minutes" echo " -q Quiet mode (ding only, no voice)" echo " NUM Bare number = seconds" exit 1 } # Parse args while [[ $# -gt 0 ]]; do case "$1" in -s) SECONDS_TOTAL="$2"; shift 2 ;; -m) SECONDS_TOTAL=$(( $2 * 60 )); shift 2 ;; -q) QUIET=true; shift ;; -h|--help) usage ;; *) if [[ "$1" =~ ^[0-9]+$ ]]; then SECONDS_TOTAL="$1"; shift else echo "Unknown argument: $1" >&2 usage fi ;; esac done if [[ "$SECONDS_TOTAL" -le 0 ]]; then usage fi # Display what we're doing if [[ "$SECONDS_TOTAL" -ge 60 ]]; then MINS=$(( SECONDS_TOTAL / 60 )) SECS=$(( SECONDS_TOTAL % 60 )) if [[ "$SECS" -gt 0 ]]; then echo "💤 Sleeping ${MINS}m ${SECS}s..." else echo "💤 Sleeping ${MINS}m..." fi else echo "💤 Sleeping ${SECONDS_TOTAL}s..." fi sleep "$SECONDS_TOTAL" # Notification paplay /usr/share/sounds/Oxygen-Im-New-Mail.ogg 2>/dev/null & if [[ "$QUIET" == false ]]; then echo "Sleep finished" | piper -m ~/.local/share/piper-voices/en_US-lessac-medium.onnx --output-raw 2>/dev/null \ | aplay -r 22050 -f S16_LE -t raw -q 2>/dev/null \ || spd-say -w "Sleep finished" 2>/dev/null || true fi echo "⏰ Done!"