本文目录导读:

我来给你介绍几种自动更新脚本的方法,从简单到复杂:
最简单的版本检查(推荐入门)
#!/bin/bash
# 简单的自我更新脚本
# 脚本当前版本
VERSION="1.0.0"
# 远程版本文件地址
REMOTE_VERSION_URL="https://example.com/version.txt"
# 脚本远程地址
SCRIPT_URL="https://example.com/script.sh"
# 脚本保存路径
SCRIPT_PATH="$0"
echo "当前版本: $VERSION"
# 检查远程版本
REMOTE_VERSION=$(curl -s "$REMOTE_VERSION_URL")
if [ "$REMOTE_VERSION" != "$VERSION" ]; then
echo "发现新版本: $REMOTE_VERSION,开始更新..."
# 下载新版本到临时文件
curl -s "$SCRIPT_URL" -o "$SCRIPT_PATH.tmp"
# 检查下载是否成功
if [ $? -eq 0 ] && [ -s "$SCRIPT_PATH.tmp" ]; then
# 替换原脚本
mv "$SCRIPT_PATH.tmp" "$SCRIPT_PATH"
chmod +x "$SCRIPT_PATH"
echo "更新完成!"
# 重新执行新脚本
exec "$SCRIPT_PATH"
else
echo "下载失败,保持原版本"
rm -f "$SCRIPT_PATH.tmp"
fi
else
echo "已经是最新版本"
fi
带备份和回滚机制
#!/bin/bash
# 带备份和回滚的更新脚本
VERSION="2.0.0"
REMOTE_INFO="https://example.com/update_info.json"
SCRIPT_PATH="$0"
BACKUP_PATH="${SCRIPT_PATH}.backup"
echo "检查更新中..."
# 获取远程版本信息
if command -v jq &> /dev/null; then
REMOTE_INFO_DATA=$(curl -s "$REMOTE_INFO")
REMOTE_VERSION=$(echo "$REMOTE_INFO_DATA" | jq -r '.version')
DOWNLOAD_URL=$(echo "$REMOTE_INFO_DATA" | jq -r '.download_url')
CHANGELOG=$(echo "$REMOTE_INFO_DATA" | jq -r '.changelog')
else
# 如果没有 jq,使用 grep/sed 解析
REMOTE_VERSION=$(curl -s "$REMOTE_INFO" | grep -o '"version":"[^"]*"' | cut -d'"' -f4)
DOWNLOAD_URL=$(curl -s "$REMOTE_INFO" | grep -o '"url":"[^"]*"' | cut -d'"' -f4)
CHANGELOG="有新版本可用"
fi
echo "当前版本: $VERSION"
echo "远程版本: $REMOTE_VERSION"
# 版本比较函数
version_compare() {
[ "$1" = "$2" ] && return 0
[ "$1" = "$(echo -e "$1\n$2" | sort -V | head -n1)" ] && return 2 || return 1
}
version_compare "$REMOTE_VERSION" "$VERSION"
RESULT=$?
if [ $RESULT -eq 1 ]; then
echo "发现新版本!更新内容:"
echo "$CHANGELOG"
# 询问用户是否更新
read -p "是否更新?(y/N): " CONFIRM
if [[ "$CONFIRM" != "y" && "$CONFIRM" != "Y" ]]; then
echo "取消更新"
exit 0
fi
# 备份当前脚本
cp "$SCRIPT_PATH" "$BACKUP_PATH"
echo "已备份当前版本到 $BACKUP_PATH"
# 下载新版本
echo "下载新版本..."
curl -sL "$DOWNLOAD_URL" -o "$SCRIPT_PATH.tmp"
# 验证下载的脚本
if [ -s "$SCRIPT_PATH.tmp" ] && file "$SCRIPT_PATH.tmp" | grep -q "script"; then
# 替换脚本
mv "$SCRIPT_PATH.tmp" "$SCRIPT_PATH"
chmod +x "$SCRIPT_PATH"
echo "更新成功!"
# 询问是否立即执行新版本
read -p "是否立即执行新版本?(Y/n): " EXECUTE_NEW
if [[ "$EXECUTE_NEW" != "n" && "$EXECUTE_NEW" != "N" ]]; then
echo "正在启动新版本..."
exec "$SCRIPT_PATH" "$@"
fi
else
echo "下载的脚本无效,回滚到备份版本"
mv "$BACKUP_PATH" "$SCRIPT_PATH"
chmod +x "$SCRIPT_PATH"
fi
else
echo "已经是最新版本"
fi
Python脚本自动更新
#!/usr/bin/env python3
"""
Python脚本自动更新示例
"""
import sys
import os
import json
import urllib.request
import hashlib
import tempfile
import shutil
import subprocess
from pathlib import Path
class AutoUpdater:
def __init__(self, version="1.0.0"):
self.version = version
self.update_url = "https://example.com/update_info.json"
self.script_path = Path(sys.argv[0]).resolve()
def check_update(self):
"""检查是否有更新"""
try:
with urllib.request.urlopen(self.update_url, timeout=10) as response:
data = json.loads(response.read())
remote_version = data['version']
download_url = data['download_url']
remote_md5 = data.get('md5', '')
changelog = data.get('changelog', '')
if self.version != remote_version:
print(f"发现新版本: {remote_version}")
if changelog:
print(f"更新说明: {changelog}")
return True, download_url, remote_md5
else:
return False, None, None
except Exception as e:
print(f"检查更新失败: {e}")
return False, None, None
def download_script(self, url):
"""下载新版本脚本"""
try:
print("下载新版本...")
with urllib.request.urlopen(url, timeout=30) as response:
data = response.read()
# 保存到临时文件
temp_file = tempfile.NamedTemporaryFile(
mode='wb',
delete=False,
suffix='.py'
)
temp_file.write(data)
temp_file.close()
return temp_file.name
except Exception as e:
print(f"下载失败: {e}")
return None
def validate_script(self, file_path, expected_md5=None):
"""验证下载的脚本"""
if not os.path.exists(file_path):
return False
if expected_md5:
with open(file_path, 'rb') as f:
md5 = hashlib.md5(f.read()).hexdigest()
if md5 != expected_md5:
print("MD5校验失败")
return False
# 检查文件是否包含有效的Python代码
try:
with open(file_path, 'r', encoding='utf-8') as f:
compile(f.read(), file_path, 'exec')
return True
except:
return False
def backup_current(self):
"""备份当前脚本"""
backup_path = Path(f"{self.script_path}.backup")
shutil.copy2(self.script_path, backup_path)
print(f"备份到: {backup_path}")
return backup_path
def update(self):
"""执行更新"""
has_update, download_url, md5 = self.check_update()
if not has_update:
print("已经是最新版本")
return True
# 备份
backup_path = self.backup_current()
# 下载新版本
new_file = self.download_script(download_url)
if not new_file:
print("更新失败")
return False
# 验证新文件
if not self.validate_script(new_file, md5):
print("新版本验证失败,回滚中...")
self.rollback(backup_path)
return False
# 替换文件
try:
os.replace(new_file, self.script_path)
os.chmod(self.script_path, 0o755) # 添加执行权限
print("更新成功!")
# 询问是否重启
choice = input("是否重新运行新版本?(y/n): ")
if choice.lower() == 'y':
print("正在启动新版本...")
subprocess.run([sys.executable, str(self.script_path)])
return True
except Exception as e:
print(f"更新失败: {e}")
self.rollback(backup_path)
return False
def rollback(self, backup_path):
"""回滚到备份版本"""
if backup_path.exists():
shutil.copy2(backup_path, self.script_path)
print("已回滚到备份版本")
def run(self):
"""主函数"""
# 检查更新
if "--check-update" in sys.argv:
self.check_update()
return
# 执行更新(默认自动检查更新)
print(f"脚本版本: {self.version}")
choice = input("是否检查更新?(y/n): ")
if choice.lower() == 'y':
self.update()
# 这里是你的主要功能代码
print("执行主要功能...")
# 你的其他代码...
if __name__ == "__main__":
updater = AutoUpdater(version="1.0.0")
updater.run()
使用Git进行更新
#!/bin/bash
# 基于Git的自动更新脚本
VERSION_FILE=".version"
REPO_URL="https://github.com/yourname/yourscript.git"
# 获取当前版本
get_current_version() {
if [ -f "$VERSION_FILE" ]; then
cat "$VERSION_FILE"
else
echo "0.0.0"
fi
}
# 检查Git仓库更新
check_git_update() {
echo "检查Git仓库更新..."
# 初始化Git仓库(如果不存在)
if [ ! -d ".git" ]; then
git init
git remote add origin "$REPO_URL"
git fetch origin 2>/dev/null
git checkout -f origin/main 2>/dev/null
return 1
fi
# 获取远程更新
git remote update 2>/dev/null
# 比较本地和远程
LOCAL=$(git rev-parse @ 2>/dev/null)
REMOTE=$(git rev-parse @{u} 2>/dev/null)
if [ "$LOCAL" != "$REMOTE" ]; then
return 0 # 有更新
else
return 1 # 没有更新
fi
}
# 执行Git更新
git_update() {
echo "发现新版本,开始更新..."
# 保存当前工作目录
CUR_DIR=$(pwd)
# 备份当前版本
cp -r "$CUR_DIR" "$CUR_DIR.backup"
# 拉取更新
git pull origin main 2>/dev/null
if [ $? -eq 0 ]; then
# 设置新版本号
echo "$(date +%Y%m%d.%H%M%S)" > "$VERSION_FILE"
echo "更新成功!"
# 询问是否重启
read -p "是否重新运行?(y/n): " RESTART
if [ "$RESTART" = "y" ]; then
exec ./$(basename "$0")
fi
else
echo "更新失败,回滚中..."
rm -rf "$CUR_DIR"
mv "$CUR_DIR.backup" "$CUR_DIR"
fi
}
# 主程序
echo "当前版本: $(get_current_version)"
if check_git_update; then
git_update
else
echo "已经是最新版本"
fi
# 以下是主要功能代码
echo "执行主要功能..."
使用建议
- 版本管理:始终保留一个稳定版本号
- 备份机制:更新前总是备份当前版本
- 验证机制:下载后验证文件完整性
- 回滚功能:万一更新失败能回退
- 安全检查:确保来源可信,可使用MD5/SHA校验
- 用户确认:重要更新前询问用户
最简单的方案(适合个人使用)
#!/bin/bash # 最简单的一行更新命令 # 放在脚本开头 curl -s https://example.com/updater.sh | bash
根据你的需求选择合适的方案,如果是生产环境建议使用带备份和回滚的方法。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播