#!/bin/bash # tmux-daemon.sh # Idempotent tmux daemon manager with config file support # Load config file if it exists SCRIPT_DIR=$(dirname "$0") SCRIPT_NAME=$(basename "$0" .sh) CONFIG_FILE="${SCRIPT_DIR}/${SCRIPT_NAME}.conf" if [ -f "$CONFIG_FILE" ]; then echo "Loading config from $CONFIG_FILE" source "$CONFIG_FILE" else echo "Config file $CONFIG_FILE not found, generating template..." cat > "$CONFIG_FILE" << 'EOF' # tmux-daemon.conf # Configuration file for tmux-daemon.sh # Session name SESSION="example" # Whether to attach to session after setup (0 or 1) ATTACH_SESSION=0 # Commands to run (array format) # Format: "workdir:::command" OR just "command" CMDS=( "ping google.com" "ping google.com" "ping google.com" "ping google.com" "ping google.com" "ping google.com" "ping google.com" ) EOF echo "Generated $CONFIG_FILE with default values. Please edit and run again." exit 0 fi # Validate required variables if [ -z "$SESSION" ]; then echo "Error: SESSION must be set in $CONFIG_FILE" >&2 exit 1 fi if [ ${#CMDS[@]} -eq 0 ]; then echo "Error: CMDS array must be set in $CONFIG_FILE" >&2 exit 1 fi echo "[main] SESSION: $SESSION" echo "[main] Commands: ${CMDS[*]}" # Create session if missing if ! tmux has-session -t $SESSION 2>/dev/null; then echo "[main] Creating tmux session: $SESSION" tmux new-session -d -s $SESSION -n win0 else echo "[main] Session $SESSION exists, reusing..." fi win=0 pane=0 for i in "${!CMDS[@]}"; do entry="${CMDS[$i]}" echo "[loop:$i] entry: $entry" if [[ "$entry" == *":::"* ]]; then workdir="${entry%%:::*}" echo "[loop:$i] workdir set from entry: $workdir" cmd="${entry#*:::}" echo "[loop:$i] cmd set from entry: $cmd" else workdir="$PWD" echo "[loop:$i] workdir set to PWD: $workdir" cmd="$entry" echo "[loop:$i] cmd set to entry: $cmd" fi echo "[loop:$i] Processing command: $cmd (workdir: $workdir)" # Determine target window/pane win=$((i / 4)) echo "[loop:$i] win updated: $win" pane=$((i % 4)) echo "[loop:$i] pane updated: $pane" # Create window if missing if ! tmux list-windows -t $SESSION | grep -q "^$win:"; then echo "[loop:$i] Creating window $win" tmux new-window -t $SESSION:$win -n win$win fi # Get current pane count in window panes=($(tmux list-panes -t $SESSION:$win -F '#P')) echo "[loop:$i] panes in window $win: ${panes[*]}" # Create missing pane if needed if [ $pane -ge ${#panes[@]} ]; then echo "[loop:$i] Splitting pane $((pane-1)) to create pane $pane in window $win" if [ $pane -eq 1 ]; then tmux split-window -h -t $SESSION:$win elif [ $pane -eq 2 ]; then tmux split-window -v -t $SESSION:$win elif [ $pane -eq 3 ]; then tmux split-window -v -t $SESSION:$win.1 fi tmux select-layout -t $SESSION:$win tiled >/dev/null fi # Check if command is already running in the pane running=$(tmux list-panes -t $SESSION:$win -F '#{pane_current_command}' | sed -n "$((pane+1))p") echo "[loop:$i] running in pane $pane: $running" if [[ "$running" == "$(basename "$cmd" | awk '{print $1}')" ]]; then echo "[loop:$i] Command already running in pane $pane, skipping..." continue fi # Create temporary script to run command in auto-restart loop tmpfile=$(mktemp) echo "[loop:$i] tmpfile created: $tmpfile" cat >"$tmpfile" <