fix: 彻底修复acme.sh安装失败问题

问题描述:
- acme.sh安装后,~/.acme.sh目录被创建但主脚本文件不存在
- 导致后续证书申请和安装失败,提示"主脚本文件不存在"

修复内容:
1. 改用官方推荐的curl管道安装方式(curl https://get.acme.sh | sh)
2. 增加不完整安装的检测和清理逻辑
3. 检查条件从仅检查目录改为同时检查目录和文件
4. 增强错误诊断信息,显示目录内容帮助排查
5. 应用到所有acme.sh方案:Let's Encrypt、ZeroSSL、Buypass

技术改进:
- 从下载到临时文件改为直接curl管道执行(更可靠)
- 添加email参数避免交互式输入
- 完善失败提示,引导用户选择其他方案

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
WanWanYun
2025-11-13 14:45:14 +08:00
parent 4bf0cd4edf
commit 410b85f9e1

View File

@@ -1344,64 +1344,38 @@ deploy_acme_letsencrypt() {
print_step "使用 acme.sh + Let's Encrypt 部署SSL证书..." print_step "使用 acme.sh + Let's Encrypt 部署SSL证书..."
# 安装acme.sh # 安装acme.sh
if [[ ! -d ~/.acme.sh ]]; then if [[ ! -d ~/.acme.sh ]] || [[ ! -f ~/.acme.sh/acme.sh ]]; then
echo "" echo ""
print_info "正在安装 acme.sh..." print_info "正在安装 acme.sh..."
print_info "使用 GitHub 官方源(国内可能较慢,请耐心等待)"
# 统一使用 GitHub 官方源(更稳定可靠) # 如果目录存在但文件不存在,先清理
INSTALL_URL="https://get.acme.sh" if [[ -d ~/.acme.sh ]] && [[ ! -f ~/.acme.sh/acme.sh ]]; then
print_warning "检测到不完整的安装,正在清理..."
# 改进的安装流程:先下载到临时文件,验证后再执行 rm -rf ~/.acme.sh
TEMP_INSTALL_SCRIPT="/tmp/acme-install-$$.sh"
print_info "正在下载安装脚本..."
if curl -fsSL "$INSTALL_URL" -o "$TEMP_INSTALL_SCRIPT"; then
# 检查下载的文件
if [[ -f "$TEMP_INSTALL_SCRIPT" ]]; then
FILE_SIZE=$(stat -c%s "$TEMP_INSTALL_SCRIPT" 2>/dev/null || stat -f%z "$TEMP_INSTALL_SCRIPT" 2>/dev/null || echo "0")
if [[ $FILE_SIZE -gt 1000 ]]; then
print_success "安装脚本下载成功 (${FILE_SIZE} bytes)"
# 显示脚本前几行以确认内容
print_info "验证脚本内容..."
if head -3 "$TEMP_INSTALL_SCRIPT" | grep -q "acme.sh"; then
print_success "脚本内容验证通过"
else
print_warning "脚本内容可能异常,但继续尝试..."
fi fi
# 执行安装(不需要参数) print_info "使用 GitHub 官方源(国内可能较慢,请耐心等待)"
print_info "正在执行安装..."
bash "$TEMP_INSTALL_SCRIPT"
install_result=$?
# 清理临时文件 # 使用官方安装方法直接通过curl管道执行
rm -f "$TEMP_INSTALL_SCRIPT" print_info "正在下载并安装..."
if curl -fsSL https://get.acme.sh | sh -s email=admin@example.com; then
install_result=$?
print_info "安装脚本执行完成,退出码: $install_result"
else
install_result=$?
print_error "安装脚本执行失败,退出码: $install_result"
fi
# 重新加载环境变量 # 重新加载环境变量
source ~/.bashrc 2>/dev/null || source ~/.profile 2>/dev/null || true source ~/.bashrc 2>/dev/null || source ~/.profile 2>/dev/null || true
# 等待文件系统同步 - 增加等待时间 # 等待文件系统同步
print_info "等待安装完成..." print_info "等待安装完成..."
sleep 5 sleep 3
else
print_error "下载的文件太小 (${FILE_SIZE} bytes),可能下载不完整"
rm -f "$TEMP_INSTALL_SCRIPT"
return 1
fi
else
print_error "安装脚本下载失败"
return 1
fi
else
print_error "无法下载安装脚本"
return 1
fi
# 验证安装是否真正成功(检查目录是否创建) # 验证安装是否真正成功
if [[ $install_result -eq 0 ]] && [[ -d ~/.acme.sh ]] && [[ -f ~/.acme.sh/acme.sh ]]; then if [[ -d ~/.acme.sh ]] && [[ -f ~/.acme.sh/acme.sh ]]; then
print_success "acme.sh 安装成功" print_success "acme.sh 安装成功"
else else
print_error "acme.sh 安装失败" print_error "acme.sh 安装失败"
@@ -1413,14 +1387,24 @@ deploy_acme_letsencrypt() {
echo " - HOME变量: $HOME" echo " - HOME变量: $HOME"
echo " - 当前用户: $(whoami)" echo " - 当前用户: $(whoami)"
echo "" echo ""
if [[ -d ~/.acme.sh ]]; then
print_info "~/.acme.sh 目录内容:"
ls -la ~/.acme.sh/ 2>&1 | head -15 || echo " 无法列出目录"
echo ""
fi
print_info "尝试查找acme.sh安装位置..." print_info "尝试查找acme.sh安装位置..."
find /root -name "acme.sh" -type f 2>/dev/null | head -5 || echo " 未找到" find /root -name "acme.sh" -type f 2>/dev/null | head -5 || echo " 未找到"
echo "" echo ""
print_warning "解决方案:" print_warning "可能的原因:"
echo " 1. 检查网络连接" echo " 1. 网络连接问题或下载超时"
echo " 2. 查看安装日志: ls -la ~ | grep acme" echo " 2. GitHub访问受限国内网络"
echo " 3. 手动安装: export ACME_USE_GITEE=1 && curl https://gitee.com/neilpang/acme.sh/raw/master/acme.sh | sh" echo " 3. curl版本过低或不支持某些功能"
echo " 4. 或访问: https://github.com/acmesh-official/acme.sh/wiki/Install-in-China" echo ""
print_warning "建议尝试其他SSL方案:"
echo " 1. 返回选择 Certbot (推荐)"
echo " 2. 或选择 [8] 暂不配置HTTPS"
echo "" echo ""
return 1 return 1
fi fi
@@ -1511,57 +1495,38 @@ deploy_acme_zerossl() {
print_step "使用 acme.sh + ZeroSSL 部署SSL证书..." print_step "使用 acme.sh + ZeroSSL 部署SSL证书..."
# 安装acme.sh使用改进的安装逻辑 # 安装acme.sh使用改进的安装逻辑
if [[ ! -d ~/.acme.sh ]]; then if [[ ! -d ~/.acme.sh ]] || [[ ! -f ~/.acme.sh/acme.sh ]]; then
echo "" echo ""
print_info "正在安装 acme.sh..." print_info "正在安装 acme.sh..."
# 如果目录存在但文件不存在,先清理
if [[ -d ~/.acme.sh ]] && [[ ! -f ~/.acme.sh/acme.sh ]]; then
print_warning "检测到不完整的安装,正在清理..."
rm -rf ~/.acme.sh
fi
print_info "使用 GitHub 官方源(国内可能较慢,请耐心等待)" print_info "使用 GitHub 官方源(国内可能较慢,请耐心等待)"
# 统一使用 GitHub 官方源(更稳定可靠) # 使用官方安装方法直接通过curl管道执行
INSTALL_URL="https://get.acme.sh" print_info "正在下载并安装..."
# 改进的安装流程:先下载到临时文件,验证后再执行 if curl -fsSL https://get.acme.sh | sh -s email=admin@example.com; then
TEMP_INSTALL_SCRIPT="/tmp/acme-install-$$.sh" install_result=$?
print_info "正在下载安装脚本..." print_info "安装脚本执行完成,退出码: $install_result"
if curl -fsSL "$INSTALL_URL" -o "$TEMP_INSTALL_SCRIPT"; then
if [[ -f "$TEMP_INSTALL_SCRIPT" ]]; then
FILE_SIZE=$(stat -c%s "$TEMP_INSTALL_SCRIPT" 2>/dev/null || stat -f%z "$TEMP_INSTALL_SCRIPT" 2>/dev/null || echo "0")
if [[ $FILE_SIZE -gt 1000 ]]; then
print_success "安装脚本下载成功 (${FILE_SIZE} bytes)"
print_info "验证脚本内容..."
if head -3 "$TEMP_INSTALL_SCRIPT" | grep -q "acme.sh"; then
print_success "脚本内容验证通过"
else else
print_warning "脚本内容可能异常,但继续尝试..." install_result=$?
print_error "安装脚本执行失败,退出码: $install_result"
fi fi
print_info "正在执行安装..." # 重新加载环境变量
bash "$TEMP_INSTALL_SCRIPT"
install_result=$?
rm -f "$TEMP_INSTALL_SCRIPT"
source ~/.bashrc 2>/dev/null || source ~/.profile 2>/dev/null || true source ~/.bashrc 2>/dev/null || source ~/.profile 2>/dev/null || true
# 等待文件系统同步
print_info "等待安装完成..." print_info "等待安装完成..."
sleep 5 sleep 3
else
print_error "下载的文件太小 (${FILE_SIZE} bytes),可能下载不完整"
rm -f "$TEMP_INSTALL_SCRIPT"
return 1
fi
else
print_error "安装脚本下载失败"
return 1
fi
else
print_error "无法下载安装脚本"
return 1
fi
# 验证安装 # 验证安装
if [[ $install_result -eq 0 ]] && [[ -d ~/.acme.sh ]] && [[ -f ~/.acme.sh/acme.sh ]]; then if [[ -d ~/.acme.sh ]] && [[ -f ~/.acme.sh/acme.sh ]]; then
print_success "acme.sh 安装成功" print_success "acme.sh 安装成功"
else else
print_error "acme.sh 安装失败" print_error "acme.sh 安装失败"
@@ -1571,6 +1536,13 @@ deploy_acme_zerossl() {
echo " - 目录 ~/.acme.sh 存在: $([ -d ~/.acme.sh ] && echo '是' || echo '否')" echo " - 目录 ~/.acme.sh 存在: $([ -d ~/.acme.sh ] && echo '是' || echo '否')"
echo " - 文件 ~/.acme.sh/acme.sh 存在: $([ -f ~/.acme.sh/acme.sh ] && echo '是' || echo '否')" echo " - 文件 ~/.acme.sh/acme.sh 存在: $([ -f ~/.acme.sh/acme.sh ] && echo '是' || echo '否')"
echo "" echo ""
if [[ -d ~/.acme.sh ]]; then
print_info "~/.acme.sh 目录内容:"
ls -la ~/.acme.sh/ 2>&1 | head -15 || echo " 无法列出目录"
echo ""
fi
return 1 return 1
fi fi
fi fi
@@ -1654,57 +1626,38 @@ deploy_acme_buypass() {
print_step "使用 acme.sh + Buypass 部署SSL证书..." print_step "使用 acme.sh + Buypass 部署SSL证书..."
# 安装acme.sh使用改进的安装逻辑 # 安装acme.sh使用改进的安装逻辑
if [[ ! -d ~/.acme.sh ]]; then if [[ ! -d ~/.acme.sh ]] || [[ ! -f ~/.acme.sh/acme.sh ]]; then
echo "" echo ""
print_info "正在安装 acme.sh..." print_info "正在安装 acme.sh..."
# 如果目录存在但文件不存在,先清理
if [[ -d ~/.acme.sh ]] && [[ ! -f ~/.acme.sh/acme.sh ]]; then
print_warning "检测到不完整的安装,正在清理..."
rm -rf ~/.acme.sh
fi
print_info "使用 GitHub 官方源(国内可能较慢,请耐心等待)" print_info "使用 GitHub 官方源(国内可能较慢,请耐心等待)"
# 统一使用 GitHub 官方源(更稳定可靠) # 使用官方安装方法直接通过curl管道执行
INSTALL_URL="https://get.acme.sh" print_info "正在下载并安装..."
# 改进的安装流程:先下载到临时文件,验证后再执行 if curl -fsSL https://get.acme.sh | sh -s email=admin@example.com; then
TEMP_INSTALL_SCRIPT="/tmp/acme-install-$$.sh" install_result=$?
print_info "正在下载安装脚本..." print_info "安装脚本执行完成,退出码: $install_result"
if curl -fsSL "$INSTALL_URL" -o "$TEMP_INSTALL_SCRIPT"; then
if [[ -f "$TEMP_INSTALL_SCRIPT" ]]; then
FILE_SIZE=$(stat -c%s "$TEMP_INSTALL_SCRIPT" 2>/dev/null || stat -f%z "$TEMP_INSTALL_SCRIPT" 2>/dev/null || echo "0")
if [[ $FILE_SIZE -gt 1000 ]]; then
print_success "安装脚本下载成功 (${FILE_SIZE} bytes)"
print_info "验证脚本内容..."
if head -3 "$TEMP_INSTALL_SCRIPT" | grep -q "acme.sh"; then
print_success "脚本内容验证通过"
else else
print_warning "脚本内容可能异常,但继续尝试..." install_result=$?
print_error "安装脚本执行失败,退出码: $install_result"
fi fi
print_info "正在执行安装..." # 重新加载环境变量
bash "$TEMP_INSTALL_SCRIPT"
install_result=$?
rm -f "$TEMP_INSTALL_SCRIPT"
source ~/.bashrc 2>/dev/null || source ~/.profile 2>/dev/null || true source ~/.bashrc 2>/dev/null || source ~/.profile 2>/dev/null || true
# 等待文件系统同步
print_info "等待安装完成..." print_info "等待安装完成..."
sleep 5 sleep 3
else
print_error "下载的文件太小 (${FILE_SIZE} bytes),可能下载不完整"
rm -f "$TEMP_INSTALL_SCRIPT"
return 1
fi
else
print_error "安装脚本下载失败"
return 1
fi
else
print_error "无法下载安装脚本"
return 1
fi
# 验证安装 # 验证安装
if [[ $install_result -eq 0 ]] && [[ -d ~/.acme.sh ]] && [[ -f ~/.acme.sh/acme.sh ]]; then if [[ -d ~/.acme.sh ]] && [[ -f ~/.acme.sh/acme.sh ]]; then
print_success "acme.sh 安装成功" print_success "acme.sh 安装成功"
else else
print_error "acme.sh 安装失败" print_error "acme.sh 安装失败"
@@ -1714,6 +1667,13 @@ deploy_acme_buypass() {
echo " - 目录 ~/.acme.sh 存在: $([ -d ~/.acme.sh ] && echo '是' || echo '否')" echo " - 目录 ~/.acme.sh 存在: $([ -d ~/.acme.sh ] && echo '是' || echo '否')"
echo " - 文件 ~/.acme.sh/acme.sh 存在: $([ -f ~/.acme.sh/acme.sh ] && echo '是' || echo '否')" echo " - 文件 ~/.acme.sh/acme.sh 存在: $([ -f ~/.acme.sh/acme.sh ] && echo '是' || echo '否')"
echo "" echo ""
if [[ -d ~/.acme.sh ]]; then
print_info "~/.acme.sh 目录内容:"
ls -la ~/.acme.sh/ 2>&1 | head -15 || echo " 无法列出目录"
echo ""
fi
return 1 return 1
fi fi
fi fi