Fix manage.sh menu input after curl|bash tty reattach.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-10-21 16:35:22 +08:00
parent e68393fe5b
commit 1714732b10
+39 -9
View File
@@ -82,10 +82,17 @@ bootstrap_repo() {
fi fi
mkdir -p "$(dirname "${INSTALL_ROOT}")" mkdir -p "$(dirname "${INSTALL_ROOT}")"
git clone -b "${GIT_BRANCH}" "${GIT_URL}" "${INSTALL_ROOT}" git clone -b "${GIT_BRANCH}" "${GIT_URL}" "${INSTALL_ROOT}"
exec bash "${INSTALL_ROOT}/deploy/manage.sh" "$@" </dev/tty exec bash "${INSTALL_ROOT}/deploy/manage.sh" "$@" </dev/tty >/dev/tty 2>/dev/tty
}
# curl|bash 时 stdin 是脚本管道,菜单 read 会立刻 EOF;挂到真实终端
attach_tty() {
# 把 0/1/2 都接到控制终端,避免只重定向 stdin 后 read 仍异常
if [[ -e /dev/tty ]]; then
exec </dev/tty >/dev/tty 2>/dev/tty
fi
} }
# curl|bash 时 stdin 是脚本管道,菜单 read 会立刻失败;改挂到真实终端
ensure_interactive_tty() { ensure_interactive_tty() {
if [[ -t 0 ]]; then if [[ -t 0 ]]; then
return 0 return 0
@@ -94,18 +101,41 @@ ensure_interactive_tty() {
if [[ -n "${REPO_ROOT}" && -f "${REPO_ROOT}/deploy/manage.sh" ]]; then if [[ -n "${REPO_ROOT}" && -f "${REPO_ROOT}/deploy/manage.sh" ]]; then
local_mgr="${REPO_ROOT}/deploy/manage.sh" local_mgr="${REPO_ROOT}/deploy/manage.sh"
fi fi
if [[ -r /dev/tty && -f "${local_mgr}" ]]; then
echo "检测到非交互 stdin(多为 curl|bash),改从终端重新启动管理器…" # 1) 同进程直接挂接 /dev/tty(不二次启动,少一层「像故障」的提示)
exec bash "${local_mgr}" "$@" </dev/tty if [[ -e /dev/tty ]] && attach_tty 2>/dev/null && [[ -t 0 ]]; then
echo "已挂接本机终端,请继续选择。"
return 0
fi fi
echo "错误: 需要交互终端才能显示菜单。" >&2
echo "请改用下列任一方式:" >&2 # 2) 回退:用本机已安装脚本重新 exec(stdin/stdout/stderr 全挂 tty)
if [[ -e /dev/tty && -f "${local_mgr}" ]]; then
echo "改用本机管理器启动: ${local_mgr}"
exec bash "${local_mgr}" "$@" </dev/tty >/dev/tty 2>/dev/tty
fi
echo "错误: 当前没有可用交互终端(curl|bash 的管道不能读菜单)。" >&2
echo "请改用:" >&2
echo " bash ${INSTALL_ROOT}/deploy/manage.sh" >&2 echo " bash ${INSTALL_ROOT}/deploy/manage.sh" >&2
echo " bash ${INSTALL_ROOT}/deploy/manage.sh update" >&2 echo " bash ${INSTALL_ROOT}/deploy/manage.sh update" >&2
echo " curl -fsSL https://git.bz121.com/dekun/gold_monitor/raw/branch/main/deploy/manage.sh | bash -s -- update" >&2 echo " curl -fsSL https://git.bz121.com/dekun/gold_monitor/raw/branch/main/deploy/manage.sh | bash -s -- update" >&2
exit 1 exit 1
} }
read_menu_choice() {
# set -e 下 read 遇 EOF 会直接退出,这里显式处理
local choice=""
if ! IFS= read -r -p "请选择: " choice </dev/tty; then
echo "" >&2
echo "错误: 读不到键盘输入(终端未挂接成功)。" >&2
echo "请直接执行: bash ${INSTALL_ROOT}/deploy/manage.sh" >&2
exit 1
fi
# 去掉 Windows 粘贴带来的 \\r
choice="${choice//$'\r'/}"
printf '%s' "${choice}"
}
run_update_quick() { run_update_quick() {
export REPO_ROOT DEPLOY_DIR LIB_DIR INSTALL_ROOT GIT_URL GIT_BRANCH export REPO_ROOT DEPLOY_DIR LIB_DIR INSTALL_ROOT GIT_URL GIT_BRANCH
# shellcheck source=/dev/null # shellcheck source=/dev/null
@@ -177,13 +207,13 @@ main_menu() {
show_banner show_banner
while true; do while true; do
show_menu show_menu
read -r -p "请选择: " choice choice="$(read_menu_choice)"
case "${choice}" in case "${choice}" in
1) bash "${LIB_DIR}/install.sh" ;; 1) bash "${LIB_DIR}/install.sh" ;;
2) bash "${LIB_DIR}/uninstall.sh" ;; 2) bash "${LIB_DIR}/uninstall.sh" ;;
3) bash "${LIB_DIR}/update.sh" ;; 3) bash "${LIB_DIR}/update.sh" ;;
0) exit 0 ;; 0) exit 0 ;;
*) echo "无效选项" ;; *) echo "无效选项: ${choice:-"(空)"}" ;;
esac esac
echo "" echo ""
done done