#!/bin/bash # 20260522 ChatGPT # $Header$ # # Example: # ./run_sync.sh little_boy_blue 14:40 # ./run_sync.sh childrens_hour 14:40 # ./run_sync.sh ./little_boy_blue 14:40 # # Optional with timeout: # ./run_sync.sh little_boy_blue 14:40 300 # set -euo pipefail if [ "$#" -lt 2 ] || [ "$#" -gt 3 ]; then echo "Usage: $0 binary_name HH:MM [run_seconds]" echo "Example: $0 little_boy_blue 14:40" echo "Example: $0 little_boy_blue 14:40 300" exit 1 fi BINARY="$1" START_TIME="$2" RUN_SECONDS="${3:-}" # If the binary name does not contain a slash, assume it is in the current directory. case "$BINARY" in */*) CMD="$BINARY" ;; *) CMD="./$BINARY" ;; esac if [ ! -x "$CMD" ]; then echo "ERROR: command is not executable: $CMD" echo echo "Check with:" echo " ls -l $CMD" echo " chmod 755 $CMD" exit 1 fi TARGET_EPOCH=$(date -d "today ${START_TIME}" +%s) NOW_EPOCH=$(date +%s) # If requested time already passed today, assume tomorrow. if [ "$TARGET_EPOCH" -le "$NOW_EPOCH" ]; then TARGET_EPOCH=$(date -d "tomorrow ${START_TIME}" +%s) fi SLEEP_SECONDS=$(( TARGET_EPOCH - NOW_EPOCH )) mkdir -p "$HOME/logs" echo "Host: $(hostname)" echo "Binary: $CMD" echo "Now: $(date '+%Y%m%d_%H%M%S %Z')" echo "Target time: $(date -d "@${TARGET_EPOCH}" '+%Y%m%d_%H%M%S %Z')" echo "Sleeping for: ${SLEEP_SECONDS} seconds" sleep "$SLEEP_SECONDS" STAMP=$(date +%Y%m%d_%H%M%S) SAFE_BINARY=$(basename "$BINARY") LOG="$HOME/logs/$(hostname)_${SAFE_BINARY}_${STAMP}.log" { echo "SYNC_START_HOST=$(hostname)" echo "SYNC_START_BINARY=$CMD" echo "SYNC_START_EPOCH=$(date +%s.%N)" echo "SYNC_START_LOCAL=$(date '+%Y%m%d_%H%M%S.%N %Z')" echo "SYNC_LOG_FILE=$LOG" echo "========================================" } | tee "$LOG" if [ -n "$RUN_SECONDS" ]; then exec timeout "$RUN_SECONDS"s "$CMD" 2>&1 | tee -a "$LOG" else exec "$CMD" 2>&1 | tee -a "$LOG" fi