fix: bootstrap tty reads, preserve CLI args, safe env write
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+25
-15
@@ -23,6 +23,15 @@ log() { echo -e "${GREEN}[+]${NC} $*"; }
|
|||||||
warn() { echo -e "${YELLOW}[!]${NC} $*"; }
|
warn() { echo -e "${YELLOW}[!]${NC} $*"; }
|
||||||
err() { echo -e "${RED}[!]${NC} $*" >&2; exit 1; }
|
err() { echo -e "${RED}[!]${NC} $*" >&2; exit 1; }
|
||||||
|
|
||||||
|
# curl | bash 时 stdin 是脚本管道,交互必须从终端读
|
||||||
|
_tty_read() {
|
||||||
|
if [[ -r /dev/tty ]]; then
|
||||||
|
read -r "$@" </dev/tty
|
||||||
|
else
|
||||||
|
read -r "$@"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
usage() {
|
usage() {
|
||||||
cat <<'EOF'
|
cat <<'EOF'
|
||||||
用法:
|
用法:
|
||||||
@@ -129,10 +138,10 @@ prompt_if_empty() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ "$secret" == "1" ]]; then
|
if [[ "$secret" == "1" ]]; then
|
||||||
read -r -s -p "$prompt: " value
|
_tty_read -s -p "$prompt: " value
|
||||||
echo ""
|
echo ""
|
||||||
else
|
else
|
||||||
read -r -p "$prompt: " value
|
_tty_read -p "$prompt: " value
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ -z "$value" && -n "$default" ]]; then
|
if [[ -z "$value" && -n "$default" ]]; then
|
||||||
@@ -148,14 +157,14 @@ generate_password() {
|
|||||||
|
|
||||||
write_env_file() {
|
write_env_file() {
|
||||||
local env_file="$INSTALL_DIR/.env"
|
local env_file="$INSTALL_DIR/.env"
|
||||||
cat > "$env_file" <<EOF
|
{
|
||||||
# 由 bootstrap.sh 自动生成
|
echo "# 由 bootstrap.sh 自动生成"
|
||||||
VPS_IP=${VPS_IP}
|
printf 'VPS_IP=%s\n' "$VPS_IP"
|
||||||
DOMAIN=${DOMAIN}
|
printf 'DOMAIN=%s\n' "$DOMAIN"
|
||||||
ACME_EMAIL=${ACME_EMAIL}
|
printf 'ACME_EMAIL=%s\n' "$ACME_EMAIL"
|
||||||
PANEL_USERNAME=${PANEL_USERNAME}
|
printf 'PANEL_USERNAME=%s\n' "$PANEL_USERNAME"
|
||||||
PANEL_PASSWORD=${PANEL_PASSWORD}
|
printf 'PANEL_PASSWORD=%s\n' "$PANEL_PASSWORD"
|
||||||
EOF
|
} > "$env_file"
|
||||||
chmod 600 "$env_file"
|
chmod 600 "$env_file"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -182,7 +191,7 @@ confirm_or_abort() {
|
|||||||
echo " 用户名: $PANEL_USERNAME"
|
echo " 用户名: $PANEL_USERNAME"
|
||||||
echo " 密码: ${PANEL_PASSWORD:0:2}****** (${#PANEL_PASSWORD} 位)"
|
echo " 密码: ${PANEL_PASSWORD:0:2}****** (${#PANEL_PASSWORD} 位)"
|
||||||
echo ""
|
echo ""
|
||||||
read -r -p "确认开始部署?(Y/n): " answer
|
_tty_read -p "确认开始部署?(Y/n): " answer
|
||||||
case "${answer:-Y}" in
|
case "${answer:-Y}" in
|
||||||
Y|y|yes|YES) ;;
|
Y|y|yes|YES) ;;
|
||||||
*) err "已取消" ;;
|
*) err "已取消" ;;
|
||||||
@@ -195,7 +204,7 @@ check_existing_install() {
|
|||||||
|
|
||||||
warn "检测到已有部署($env_file)"
|
warn "检测到已有部署($env_file)"
|
||||||
local answer=""
|
local answer=""
|
||||||
read -r -p "是否重新部署?将覆盖 .env 并重新安装 (y/N): " answer
|
_tty_read -p "是否重新部署?将覆盖 .env 并重新安装 (y/N): " answer
|
||||||
case "${answer:-N}" in
|
case "${answer:-N}" in
|
||||||
y|Y|yes|YES) ;;
|
y|Y|yes|YES) ;;
|
||||||
*) err "已取消。若要更新代码请: cd $INSTALL_DIR && git pull" ;;
|
*) err "已取消。若要更新代码请: cd $INSTALL_DIR && git pull" ;;
|
||||||
@@ -245,6 +254,7 @@ print_success() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# ── 参数解析 ──
|
# ── 参数解析 ──
|
||||||
|
_CLI_ARGS=("$@")
|
||||||
DOMAIN=""
|
DOMAIN=""
|
||||||
ACME_EMAIL=""
|
ACME_EMAIL=""
|
||||||
PANEL_USERNAME=""
|
PANEL_USERNAME=""
|
||||||
@@ -268,7 +278,7 @@ check_os
|
|||||||
|
|
||||||
# curl | bash 时先 clone,再用仓库内脚本继续
|
# curl | bash 时先 clone,再用仓库内脚本继续
|
||||||
ensure_repo
|
ensure_repo
|
||||||
reexec_from_repo "$@"
|
reexec_from_repo "${_CLI_ARGS[@]}"
|
||||||
|
|
||||||
print_banner
|
print_banner
|
||||||
|
|
||||||
@@ -289,7 +299,7 @@ valid_email "$ACME_EMAIL" || err "邮箱格式无效: $ACME_EMAIL"
|
|||||||
[[ -n "$PANEL_USERNAME" ]] || err "用户名不能为空"
|
[[ -n "$PANEL_USERNAME" ]] || err "用户名不能为空"
|
||||||
|
|
||||||
if [[ -z "$PANEL_PASSWORD" ]]; then
|
if [[ -z "$PANEL_PASSWORD" ]]; then
|
||||||
read -r -s -p "面板密码 (留空自动生成): " PANEL_PASSWORD
|
_tty_read -s -p "面板密码 (留空自动生成): " PANEL_PASSWORD
|
||||||
echo ""
|
echo ""
|
||||||
fi
|
fi
|
||||||
if [[ -z "$PANEL_PASSWORD" ]]; then
|
if [[ -z "$PANEL_PASSWORD" ]]; then
|
||||||
@@ -304,7 +314,7 @@ fi
|
|||||||
if [[ "$RESOLVED_IP" != "$VPS_IP" ]]; then
|
if [[ "$RESOLVED_IP" != "$VPS_IP" ]]; then
|
||||||
warn "域名 $DOMAIN 解析为 $RESOLVED_IP,本机公网 IP 为 $VPS_IP"
|
warn "域名 $DOMAIN 解析为 $RESOLVED_IP,本机公网 IP 为 $VPS_IP"
|
||||||
if [[ "$ASSUME_YES" -eq 0 ]]; then
|
if [[ "$ASSUME_YES" -eq 0 ]]; then
|
||||||
read -r -p "DNS 可能未生效,继续?(y/N): " dns_ok
|
_tty_read -p "DNS 可能未生效,继续?(y/N): " dns_ok
|
||||||
case "${dns_ok:-N}" in
|
case "${dns_ok:-N}" in
|
||||||
y|Y|yes|YES) ;;
|
y|Y|yes|YES) ;;
|
||||||
*) err "请先修正 DNS 后重试" ;;
|
*) err "请先修正 DNS 后重试" ;;
|
||||||
|
|||||||
+2
-1
@@ -168,7 +168,8 @@ bash "$ROOT_DIR/scripts/enable-panel-https.sh"
|
|||||||
rm -f /etc/nginx/sites-enabled/panel /etc/nginx/sites-available/panel
|
rm -f /etc/nginx/sites-enabled/panel /etc/nginx/sites-available/panel
|
||||||
|
|
||||||
log "安装 Python 面板依赖 ..."
|
log "安装 Python 面板依赖 ..."
|
||||||
python3 -m venv "$ROOT_DIR/panel/venv"
|
python3 -m venv --clear "$ROOT_DIR/panel/venv" 2>/dev/null \
|
||||||
|
|| { rm -rf "$ROOT_DIR/panel/venv"; python3 -m venv "$ROOT_DIR/panel/venv"; }
|
||||||
"$ROOT_DIR/panel/venv/bin/pip" install -q --upgrade pip
|
"$ROOT_DIR/panel/venv/bin/pip" install -q --upgrade pip
|
||||||
"$ROOT_DIR/panel/venv/bin/pip" install -q -r "$ROOT_DIR/panel/requirements.txt"
|
"$ROOT_DIR/panel/venv/bin/pip" install -q -r "$ROOT_DIR/panel/requirements.txt"
|
||||||
"$ROOT_DIR/panel/venv/bin/python" -c "import flask" \
|
"$ROOT_DIR/panel/venv/bin/python" -c "import flask" \
|
||||||
|
|||||||
Reference in New Issue
Block a user