本文目录导读:

我来提供一个跨平台的自动更新并重启脚本方案,包括 Linux 和 Windows 系统。
Linux 系统自动更新脚本
Bash 脚本示例
#!/bin/bash
# 自动更新并重启脚本
# 文件名: auto_update.sh
# 配置变量
APP_NAME="your-application"
APP_PATH="/opt/app/$APP_NAME"
BACKUP_DIR="/opt/backup/$APP_NAME"
LOG_FILE="/var/log/$APP_NAME-update.log"
UPDATE_URL="https://your-update-server.com/downloads/$APP_NAME-latest.tar.gz"
HEALTH_CHECK_URL="http://localhost:8080/health"
# 日志函数
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
}
# 检查更新
check_update() {
log "检查新版本..."
# 获取当前版本
local current_version=$(cat "$APP_PATH/version.txt" 2>/dev/null || echo "0.0.0")
# 获取远程版本(示例使用 HTTP 请求)
local remote_version=$(curl -s "$UPDATE_URL/version.txt" 2>/dev/null || echo "$current_version")
if [ "$current_version" != "$remote_version" ]; then
log "发现新版本: $remote_version (当前: $current_version)"
return 0
else
log "已是最新版本"
return 1
fi
}
# 备份当前版本
backup_app() {
log "备份当前版本..."
mkdir -p "$BACKUP_DIR"
tar -czf "$BACKUP_DIR/backup-$(date '+%Y%m%d%H%M%S').tar.gz" -C "$APP_PATH" .
log "备份完成"
}
# 下载更新
download_update() {
log "下载更新..."
local tmp_file="/tmp/$APP_NAME-update.tar.gz"
if wget -O "$tmp_file" "$UPDATE_URL"; then
log "下载完成"
echo "$tmp_file"
else
log "下载失败"
return 1
fi
}
# 停止应用
stop_app() {
log "停止应用服务..."
# 使用 systemctl 停止服务
if systemctl is-active --quiet "$APP_NAME"; then
systemctl stop "$APP_NAME"
log "服务已停止"
else
log "服务未运行"
fi
# 等待进程完全停止
sleep 5
}
# 安装更新
install_update() {
local update_file=$1
log "安装更新..."
# 解压更新文件
if tar -xzf "$update_file" -C "$APP_PATH"; then
log "更新文件解压成功"
rm -f "$update_file"
return 0
else
log "更新文件解压失败"
return 1
fi
}
# 健康检查
health_check() {
log "执行健康检查..."
local max_retries=10
local retry_count=0
while [ $retry_count -lt $max_retries ]; do
if curl -s -f "$HEALTH_CHECK_URL" > /dev/null 2>&1; then
log "健康检查通过"
return 0
fi
retry_count=$((retry_count + 1))
sleep 3
done
log "健康检查失败,需要回滚"
return 1
}
# 回滚
rollback() {
log "执行回滚操作..."
stop_app
# 恢复到最新备份
local latest_backup=$(ls -t "$BACKUP_DIR"/*.tar.gz 2>/dev/null | head -1)
if [ -n "$latest_backup" ]; then
rm -rf "$APP_PATH"/*
tar -xzf "$latest_backup" -C "$APP_PATH"
log "回滚完成"
else
log "未找到备份文件"
return 1
fi
}
# 主更新流程
main() {
log "========== 开始自动更新 =========="
# 检查更新
if ! check_update; then
log "无需更新"
exit 0
fi
# 备份当前版本
backup_app
# 下载更新
local update_file=$(download_update)
if [ -z "$update_file" ]; then
log "更新失败"
exit 1
fi
# 停止应用
stop_app
# 安装更新
if ! install_update "$update_file"; then
rollback
exit 1
fi
# 启动应用
log "启动应用服务..."
systemctl start "$APP_NAME"
# 健康检查
if ! health_check; then
rollback
log "更新失败,已回滚到上一版本"
exit 1
fi
log "自动更新成功完成!"
}
# 执行主函数
main
Windows 系统自动更新脚本
PowerShell 脚本示例
# 自动更新并重启脚本
# 文件名: auto_update.ps1
param(
[string]$AppName = "YourApplication",
[string]$AppPath = "C:\Program Files\YourApplication",
[string]$UpdateUrl = "https://your-update-server.com/downloads/",
[string]$BackupPath = "C:\Backup\$AppName"
)
# 日志函数
function Write-Log {
param([string]$Message)
$logEntry = "[$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')] $Message"
Write-Host $logEntry
Add-Content -Path "$env:TEMP\$AppName-update.log" -Value $logEntry
}
# 检查更新
function Check-Update {
Write-Log "检查新版本..."
try {
$currentVersion = (Get-Item "$AppPath\version.txt" -ErrorAction SilentlyContinue) ?
(Get-Content "$AppPath\version.txt") : "0.0.0"
$remoteVersion = (Invoke-WebRequest -Uri "$UpdateUrl/version.txt" -UseBasicParsing -ErrorAction SilentlyContinue).Content
if ($currentVersion -ne $remoteVersion) {
Write-Log "发现新版本: $remoteVersion (当前: $currentVersion)"
return $true
} else {
Write-Log "已是最新版本"
return $false
}
}
catch {
Write-Log "检查更新失败: $_"
return $false
}
}
# 停止服务
function Stop-Application {
Write-Log "停止应用服务..."
# 停止 Windows 服务
if (Get-Service "$AppName" -ErrorAction SilentlyContinue) {
if ((Get-Service "$AppName").Status -eq 'Running') {
Stop-Service "$AppName"
Write-Log "服务已停止"
}
}
# 停止进程
Get-Process -Name "$AppName" -ErrorAction SilentlyContinue | Stop-Process -Force
Start-Sleep -Seconds 5
}
# 备份应用
function Backup-Application {
Write-Log "备份当前版本..."
if (-not (Test-Path $BackupPath)) {
New-Item -ItemType Directory -Path $BackupPath -Force | Out-Null
}
$backupFile = Join-Path $BackupPath "backup-$(Get-Date -Format 'yyyyMMddHHmmss').zip"
Compress-Archive -Path "$AppPath\*" -DestinationPath $backupFile -Force
Write-Log "备份完成: $backupFile"
return $backupFile
}
# 下载更新
function Download-Update {
Write-Log "下载更新..."
$downloadUrl = "$UpdateUrl/$AppName-latest.zip"
$tempFile = Join-Path $env:TEMP "$AppName-update.zip"
try {
Invoke-WebRequest -Uri $downloadUrl -OutFile $tempFile -UseBasicParsing
Write-Log "下载完成"
return $tempFile
}
catch {
Write-Log "下载失败: $_"
return $null
}
}
# 安装更新
function Install-Update {
param([string]$UpdateFile)
Write-Log "安装更新..."
try {
# 备份当前配置文件
if (Test-Path "$AppPath\config.json") {
Copy-Item "$AppPath\config.json" "$env:TEMP\config.json.backup"
}
# 清空并解压更新
Remove-Item "$AppPath\*" -Recurse -Force -ErrorAction SilentlyContinue
Expand-Archive -Path $UpdateFile -DestinationPath $AppPath -Force
# 恢复配置文件
if (Test-Path "$env:TEMP\config.json.backup") {
Copy-Item "$env:TEMP\config.json.backup" "$AppPath\config.json" -Force
Remove-Item "$env:TEMP\config.json.backup"
}
Remove-Item $UpdateFile -Force
Write-Log "更新安装成功"
return $true
}
catch {
Write-Log "更新安装失败: $_"
return $false
}
}
# 启动应用
function Start-Application {
Write-Log "启动应用服务..."
# 启动 Windows 服务
if (Get-Service "$AppName" -ErrorAction SilentlyContinue) {
Start-Service "$AppName"
}
# 或者启动可执行文件
elseif (Test-Path "$AppPath\$AppName.exe") {
Start-Process -FilePath "$AppPath\$AppName.exe"
}
Start-Sleep -Seconds 10
}
# 健康检查
function Test-Health {
param([string]$HealthCheckUrl = "http://localhost:8080/health")
Write-Log "执行健康检查..."
$maxRetries = 10
$retryCount = 0
while ($retryCount -lt $maxRetries) {
try {
$response = Invoke-WebRequest -Uri $HealthCheckUrl -UseBasicParsing -ErrorAction Stop
if ($response.StatusCode -eq 200) {
Write-Log "健康检查通过"
return $true
}
}
catch {
$retryCount++
Start-Sleep -Seconds 3
}
}
Write-Log "健康检查失败"
return $false
}
# 回滚
function Rollback-Update {
param([string]$BackupFile)
Write-Log "执行回滚操作..."
Stop-Application
try {
Remove-Item "$AppPath\*" -Recurse -Force -ErrorAction SilentlyContinue
Expand-Archive -Path $BackupFile -DestinationPath $AppPath -Force
Write-Log "回滚完成"
Start-Application
return $true
}
catch {
Write-Log "回滚失败: $_"
return $false
}
}
# 主函数
function Main {
Write-Log "========== 开始自动更新 =========="
# 检查更新
if (-not (Check-Update)) {
Write-Log "无需更新"
exit 0
}
# 备份
$backupFile = Backup-Application
# 下载更新
$updateFile = Download-Update
if (-not $updateFile) {
Write-Log "更新失败"
exit 1
}
# 停止应用
Stop-Application
# 安装更新
if (-not (Install-Update -UpdateFile $updateFile)) {
Rollback-Update -BackupFile $backupFile
exit 1
}
# 启动应用
Start-Application
# 健康检查
if (-not (Test-Health)) {
Write-Log "更新失败,正在回滚..."
Rollback-Update -BackupFile $backupFile
exit 1
}
Write-Log "自动更新成功完成!"
}
# 执行主函数
Main
任务计划配置
Linux Cron 配置
# 每天凌晨3点执行更新检查 0 3 * * * /path/to/auto_update.sh # 每小时的15分执行 15 * * * * /path/to/auto_update.sh
Windows 任务计划程序
# 创建计划任务 $action = New-ScheduledTaskAction -Execute "PowerShell.exe" -Argument "-File C:\Scripts\auto_update.ps1" $trigger = New-ScheduledTaskTrigger -Daily -At 3am $principal = New-ScheduledTaskPrincipal -UserId "SYSTEM" -LogonType ServiceAccount $settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries Register-ScheduledTask -TaskName "AutoUpdate" -Action $action -Trigger $trigger -Principal $principal -Settings $settings
使用建议
- 测试环境验证:先在测试环境运行脚本
- 错误处理:确保有完整的错误处理和回滚机制
- 监控告警:集成监控系统和告警通知
- 增量更新:考虑使用增量更新减少下载量
- 版本控制:维护更新历史的版本记录
- 并发控制:防止多个更新实例同时运行
需要我针对特定场景(如 Docker 容器、云服务等)提供专门的更新脚本吗?