tmux-management 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. #!/usr/bin/env bash
  2. # tmux‑management2 – open a tiled tmux window with one pane per host.
  3. # Each pane attaches to (or creates) a tmux session called $REMOTE_SESSION
  4. # on the target host. The local host is always the *last* (active) pane.
  5. set -euo pipefail
  6. # Configuration (override with env vars if desired)
  7. HOSTS=(workstation laptop vm-fedora42) # hosts in pane order
  8. REMOTE_SESSION=${REMOTE_SESSION:-main} # tmux session on remotes
  9. SYNCHRONIZE=${SYNCHRONIZE:-1} # 1 = broadcast keystrokes
  10. INCLUDE_LOCAL=${INCLUDE_LOCAL:-1} # 0 = skip local host
  11. LOCAL_SHELL_ONLY=${LOCAL_SHELL_ONLY:-0} # 1 = plain shell locally
  12. DEBUG=${DEBUG:-0}
  13. debug() { if (( DEBUG )); then echo "Debug: $*"; fi; }
  14. # Returns 0 if $2 is found in nameref array $1
  15. array_contains() {
  16. local -n arr=$1
  17. local needle=$2
  18. for element in "${arr[@]}"; do
  19. [[ "$element" == "$needle" ]] && return 0
  20. done
  21. return 1
  22. }
  23. LOCAL=$(hostname -s)
  24. # Build TARGETS list so that LOCAL is always last
  25. TARGETS=()
  26. for h in "${HOSTS[@]}"; do
  27. [[ $h != "$LOCAL" ]] && TARGETS+=("$h")
  28. done
  29. if (( INCLUDE_LOCAL )); then
  30. TARGETS+=("$LOCAL")
  31. fi
  32. (( ${#TARGETS[@]} )) || { echo "No hosts to connect to."; exit 1; }
  33. SESSION=$(IFS=-; echo "${TARGETS[*]}")
  34. debug "Session : $SESSION"
  35. debug "Targets : ${TARGETS[*]}"
  36. # Re‑attach if session already exists
  37. if tmux has-session -t "$SESSION" 2>/dev/null; then
  38. exec tmux attach -t "$SESSION"
  39. fi
  40. # Builds the command that will run inside a pane
  41. open_cmd() {
  42. local tgt=$1
  43. if [[ $tgt == "$LOCAL" ]]; then
  44. if (( LOCAL_SHELL_ONLY )); then
  45. printf '%q -l' "${SHELL:-bash}"
  46. else
  47. printf 'tmux -L %q new -A -s %q' "${SESSION}_local" "$REMOTE_SESSION"
  48. fi
  49. else
  50. printf 'ssh -t %q tmux new -A -s %q' "$tgt" "$REMOTE_SESSION"
  51. fi
  52. }
  53. # Create the first pane
  54. tmux new-session -d -s "$SESSION" -n "$SESSION" "$(open_cmd "${TARGETS[0]}")"
  55. # Create remaining panes
  56. for tgt in "${TARGETS[@]:1}"; do
  57. tmux split-window -t "$SESSION:0" -h "$(open_cmd "$tgt")"
  58. done
  59. tmux select-layout -t "$SESSION:0" tiled
  60. ((SYNCHRONIZE)) && tmux setw -t "$SESSION:0" synchronize-panes on
  61. # Activate the last pane (local host)
  62. local_index=$(( ${#TARGETS[@]} - 1 ))
  63. tmux select-pane -t "$SESSION:0.$local_index"
  64. exec tmux attach -t "$SESSION"