-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathstop.sh
More file actions
executable file
·71 lines (59 loc) · 2.2 KB
/
Copy pathstop.sh
File metadata and controls
executable file
·71 lines (59 loc) · 2.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#!/usr/bin/env bash
# Stops the Vectis backend (FastAPI/uvicorn, port 8000) and frontend (Vite,
# port 5173) dev servers started by start.sh.
#
# start.sh doesn't write a PID file (it just backgrounds two child processes
# and traps EXIT/INT/TERM to kill them) so if that terminal was closed
# instead of Ctrl-C'd, or the script was backgrounded/disowned, the servers
# can be left running as orphans. This finds them by the port they're
# listening on (falling back to a command-name match) and kills them
# directly, which works regardless of how start.sh exited.
set -uo pipefail
BACKEND_PORT=8000
FRONTEND_PORT=5173
killed_any=0
kill_by_port() {
local port="$1" label="$2"
local pids
# Not just -sTCP:LISTEN: a crashed/orphaned process can leave the port
# bound in a non-LISTEN state (e.g. CLOSED) that still blocks a new
# process from binding, so check every socket on the port.
pids="$(lsof -ti "tcp:${port}" 2>/dev/null || true)"
if [[ -z "$pids" ]]; then
echo "No process on port $port ($label)."
return
fi
echo "Stopping $label on port $port (pid(s): $pids)..."
# shellcheck disable=SC2086
kill $pids 2>/dev/null || true
# Give it a moment to exit cleanly, then force-kill anything still alive.
for _ in 1 2 3 4 5; do
sleep 0.5
pids="$(lsof -ti "tcp:${port}" 2>/dev/null || true)"
[[ -z "$pids" ]] && break
done
if [[ -n "$pids" ]]; then
echo " still running, force-killing: $pids"
# shellcheck disable=SC2086
kill -9 $pids 2>/dev/null || true
fi
killed_any=1
}
kill_by_port "$BACKEND_PORT" "backend (uvicorn)"
kill_by_port "$FRONTEND_PORT" "frontend (vite)"
# Belt-and-suspenders: uvicorn's --reload watcher and any stray `npm run
# dev`/vite process for this project may not always be the one holding the
# listening socket. Sweep by command line too, scoped tightly enough not to
# catch unrelated processes on the machine.
pattern_pids="$(pgrep -f "uvicorn main:app" 2>/dev/null || true)"
if [[ -n "$pattern_pids" ]]; then
echo "Stopping stray uvicorn process(es): $pattern_pids"
# shellcheck disable=SC2086
kill -9 $pattern_pids 2>/dev/null || true
killed_any=1
fi
if [[ "$killed_any" -eq 1 ]]; then
echo "Done."
else
echo "Nothing was running."
fi