fix(dev): 端口探测改为 lsof 优先,修复 dev.sh 误判"未运行"
macOS 上 /usr/local/bin/ss 由 iproute2mac 提供(netstat 包装),输出以 TAB 分隔且 -p 不产出 pid=,导致 listener_pids 恒为空: - port_in_use 永远为假 → start 重复拉起 uvicorn 并报 [Errno 48] Address already in use,最终 die "后端启动超时" - status 误报"未运行",stop 定位不到监听进程 改为 lsof 优先、ss 兜底(保留 Linux 真 iproute2 的 pid= 提取),并用 ([^0-9]|$) 界定端口边界以兼容空格/TAB 两种分隔。显式 if 替代 [[ ]] && ——bash 3.2 在 set -e 下会因中途失败的 && 列表直接退出。
This commit is contained in:
+20
-8
@@ -41,15 +41,27 @@ die() { echo "[dev.sh] 错误: $*" >&2; exit 1; }
|
|||||||
# ---------- 进程探测 ----------
|
# ---------- 进程探测 ----------
|
||||||
|
|
||||||
# 监听指定端口的 pid(无则空)
|
# 监听指定端口的 pid(无则空)
|
||||||
listener_pids() { # $1 port —— ss 优先(lsof 在部分环境对 socket 不可靠)
|
# 取值顺序:lsof → ss。
|
||||||
if command -v ss >/dev/null 2>&1; then
|
# 不能把 ss 放在首位:macOS 上 /usr/local/bin/ss 常由 iproute2mac 提供(netstat 包装),
|
||||||
ss -tlnp 2>/dev/null | awk -v p=":$1 " '
|
# 其输出以 TAB 分隔且 -p 不产出 pid=,会让匹配恒为空 → port_in_use 永远为假 →
|
||||||
$0 ~ p && /LISTEN/ {
|
# start 重复拉起进程并报 [Errno 48] Address already in use,status 也误报"未运行"。
|
||||||
if (match($0, /pid=[0-9]+/)) print substr($0, RSTART+4, RLENGTH-4)
|
# 真实 iproute2(Linux)的 ss 仍作为兜底,此时可从 users:(("x",pid=NNN)) 取到 pid。
|
||||||
}'
|
listener_pids() { # $1 port
|
||||||
elif command -v lsof >/dev/null 2>&1; then
|
local pids=""
|
||||||
lsof -t -iTCP:"$1" -sTCP:LISTEN 2>/dev/null || true
|
if command -v lsof >/dev/null 2>&1; then
|
||||||
|
pids="$(lsof -t -iTCP:"$1" -sTCP:LISTEN 2>/dev/null || true)"
|
||||||
fi
|
fi
|
||||||
|
if [[ -z "$pids" ]] && command -v ss >/dev/null 2>&1; then
|
||||||
|
# ([^0-9]|$) 界定端口边界:兼容 ss 的空格与 TAB 两种分隔,且避免匹配到更长的端口号
|
||||||
|
pids="$(ss -tlnp 2>/dev/null | awk -v p=":$1" '
|
||||||
|
$0 ~ (p "([^0-9]|$)") && /LISTEN/ {
|
||||||
|
if (match($0, /pid=[0-9]+/)) print substr($0, RSTART+4, RLENGTH-4)
|
||||||
|
}' || true)"
|
||||||
|
fi
|
||||||
|
if [[ -n "$pids" ]]; then
|
||||||
|
printf '%s\n' "$pids"
|
||||||
|
fi
|
||||||
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
port_in_use() { [[ -n "$(listener_pids "$1")" ]]; }
|
port_in_use() { [[ -n "$(listener_pids "$1")" ]]; }
|
||||||
|
|||||||
Reference in New Issue
Block a user