返回 JoyAI-Echo
find-sessions.sh
1 #!/usr/bin/env bash
2 set -euo pipefail
3
4 usage() {
5 cat <<'USAGE'
6 Usage: find-sessions.sh [-L socket-name|-S socket-path|-A] [-q pattern]
7
8 List tmux sessions on a socket (default tmux socket if none provided).
9
10 Options:
11 -L, --socket tmux socket name (passed to tmux -L)
12 -S, --socket-path tmux socket path (passed to tmux -S)
13 -A, --all scan all sockets under NANOBOT_TMUX_SOCKET_DIR
14 -q, --query case-insensitive substring to filter session names
15 -h, --help show this help
16 USAGE
17 }
18
19 socket_name=""
20 socket_path=""
21 query=""
22 scan_all=false
23 socket_dir="${NANOBOT_TMUX_SOCKET_DIR:-${TMPDIR:-/tmp}/nanobot-tmux-sockets}"
24
25 while [[ $# -gt 0 ]]; do
26 case "$1" in
27 -L|--socket) socket_name="${2-}"; shift 2 ;;
28 -S|--socket-path) socket_path="${2-}"; shift 2 ;;
29 -A|--all) scan_all=true; shift ;;
30 -q|--query) query="${2-}"; shift 2 ;;
31 -h|--help) usage; exit 0 ;;
32 *) echo "Unknown option: $1" >&2; usage; exit 1 ;;
33 esac
34 done
35
36 if [[ "$scan_all" == true && ( -n "$socket_name" || -n "$socket_path" ) ]]; then
37 echo "Cannot combine --all with -L or -S" >&2
38 exit 1
39 fi
40
41 if [[ -n "$socket_name" && -n "$socket_path" ]]; then
42 echo "Use either -L or -S, not both" >&2
43 exit 1
44 fi
45
46 if ! command -v tmux >/dev/null 2>&1; then
47 echo "tmux not found in PATH" >&2
48 exit 1
49 fi
50
51 list_sessions() {
52 local label="$1"; shift
53 local tmux_cmd=(tmux "$@")
54
55 if ! sessions="$("${tmux_cmd[@]}" list-sessions -F '#{session_name}\t#{session_attached}\t#{session_created_string}' 2>/dev/null)"; then
56 echo "No tmux server found on $label" >&2
57 return 1
58 fi
59
60 if [[ -n "$query" ]]; then
61 sessions="$(printf '%s\n' "$sessions" | grep -i -- "$query" || true)"
62 fi
63
64 if [[ -z "$sessions" ]]; then
65 echo "No sessions found on $label"
66 return 0
67 fi
68
69 echo "Sessions on $label:"
70 printf '%s\n' "$sessions" | while IFS=$'\t' read -r name attached created; do
71 attached_label=$([[ "$attached" == "1" ]] && echo "attached" || echo "detached")
72 printf ' - %s (%s, started %s)\n' "$name" "$attached_label" "$created"
73 done
74 }
75
76 if [[ "$scan_all" == true ]]; then
77 if [[ ! -d "$socket_dir" ]]; then
78 echo "Socket directory not found: $socket_dir" >&2
79 exit 1
80 fi
81
82 shopt -s nullglob
83 sockets=("$socket_dir"/*)
84 shopt -u nullglob
85
86 if [[ "${#sockets[@]}" -eq 0 ]]; then
87 echo "No sockets found under $socket_dir" >&2
88 exit 1
89 fi
90
91 exit_code=0
92 for sock in "${sockets[@]}"; do
93 if [[ ! -S "$sock" ]]; then
94 continue
95 fi
96 list_sessions "socket path '$sock'" -S "$sock" || exit_code=$?
97 done
98 exit "$exit_code"
99 fi
100
101 tmux_cmd=(tmux)
102 socket_label="default socket"
103
104 if [[ -n "$socket_name" ]]; then
105 tmux_cmd+=(-L "$socket_name")
106 socket_label="socket name '$socket_name'"
107 elif [[ -n "$socket_path" ]]; then
108 tmux_cmd+=(-S "$socket_path")
109 socket_label="socket path '$socket_path'"
110 fi
111
112 list_sessions "$socket_label" "${tmux_cmd[@]:1}"
113
113 lines BASH