diff --git a/deploy/manage.sh b/deploy/manage.sh index 658f86a..7a7ad93 100644 --- a/deploy/manage.sh +++ b/deploy/manage.sh @@ -82,10 +82,17 @@ bootstrap_repo() { fi mkdir -p "$(dirname "${INSTALL_ROOT}")" git clone -b "${GIT_BRANCH}" "${GIT_URL}" "${INSTALL_ROOT}" - exec bash "${INSTALL_ROOT}/deploy/manage.sh" "$@" /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 2>/dev/tty + fi } -# curl|bash 时 stdin 是脚本管道,菜单 read 会立刻失败;改挂到真实终端 ensure_interactive_tty() { if [[ -t 0 ]]; then return 0 @@ -94,18 +101,41 @@ ensure_interactive_tty() { if [[ -n "${REPO_ROOT}" && -f "${REPO_ROOT}/deploy/manage.sh" ]]; then local_mgr="${REPO_ROOT}/deploy/manage.sh" fi - if [[ -r /dev/tty && -f "${local_mgr}" ]]; then - echo "检测到非交互 stdin(多为 curl|bash),改从终端重新启动管理器…" - exec bash "${local_mgr}" "$@" /dev/null && [[ -t 0 ]]; then + echo "已挂接本机终端,请继续选择。" + return 0 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 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 update" >&2 echo " curl -fsSL https://git.bz121.com/dekun/gold_monitor/raw/branch/main/deploy/manage.sh | bash -s -- update" >&2 exit 1 } +read_menu_choice() { + # set -e 下 read 遇 EOF 会直接退出,这里显式处理 + local choice="" + if ! IFS= read -r -p "请选择: " choice &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() { export REPO_ROOT DEPLOY_DIR LIB_DIR INSTALL_ROOT GIT_URL GIT_BRANCH # shellcheck source=/dev/null @@ -177,13 +207,13 @@ main_menu() { show_banner while true; do show_menu - read -r -p "请选择: " choice + choice="$(read_menu_choice)" case "${choice}" in 1) bash "${LIB_DIR}/install.sh" ;; 2) bash "${LIB_DIR}/uninstall.sh" ;; 3) bash "${LIB_DIR}/update.sh" ;; 0) exit 0 ;; - *) echo "无效选项" ;; + *) echo "无效选项: ${choice:-"(空)"}" ;; esac echo "" done