➜ lsblk -o NAME,SIZE,TYPE,MOUNTPOINT | grep mmcblk mmcblk0 14.6G disk ├─mmcblk0p1 285M part /boot/efi ├─mmcblk0p2 6.5G part / └─mmcblk0p3 7.7G part /zspace
➜ lsblk -o NAME,SIZE,TYPE,MOUNTPOINT | grep mmcblk mmcblk0 29.1G disk ├─mmcblk0p1 12M part ├─mmcblk0p2 512M part /boot ├─mmcblk0p3 2G part /rom ├─mmcblk0p4 2G part ├─mmcblk0p5 7G part /overlay ├─mmcblk0p6 12G part /zspace ├─mmcblk0p7 3G part /zspace/applications/logs ├─mmcblk0p8 300M part └─mmcblk0p9 2G part mmcblk0boot0 4M disk mmcblk0boot1 4M disk ➜ df -h / Filesystem Size Used Avail Use% Mounted on overlay 6.8G 1.2G 5.3G 19% /
if [ "$title_needs_replace" -eq 0 ]; then log"INFO""文件已符合目标状态,无需修改。" return 0 fi
# 备份并替换 backup_file cp"$file_path""$file_path.tmp" || { log"ERROR""创建临时文件失败。"; exit 1; } if [ "$title_needs_replace" -eq 1 ]; then if sed "s|$title_search|$title_replace|""$file_path.tmp" > "$file_path.tmp2" && mv"$file_path.tmp2""$file_path.tmp"; then log"INFO""替换成功:已更新标题。" else mv"$file_path.tmp""$file_path" log"ERROR""标题替换失败,已回滚。" exit 1 fi fi
# 复制自定义文件 copy_custom_files() { local target_dir="${CONFIG[5]#*=}" for src in"${CONFIG[3]#*=}""${CONFIG[4]#*=}"; do if [ ! -f "$src" ]; then log"ERROR""源文件 $src 不存在。" exit 1 fi if ! cp -f "$src""$target_dir"; then log"ERROR""无法复制 $src 到 $target_dir。" exit 1 fi done log"INFO""复制成功:已更新 custom.min.css 和 favicon.ico。" }
# 同步函数 sync_directories() { local source_dir="$1" local target_dir="$2"
# 检查源目录是否存在 if [ ! -d "$source_dir" ]; then log"源目录 $source_dir 不存在。" exit 1 fi
# 检查目标目录是否存在,如果不存在则创建 if [ ! -d "$target_dir" ]; then log"警告:目标目录 $target_dir 不存在,正在创建..." mkdir -p "$target_dir" if [ $? -ne 0 ]; then log"创建目标目录 $target_dir 失败。" exit 1 fi fi
-- 步骤1:创建临时表 CREATE TEMPORARY TABLE temp_zvideo ( id INTEGER, title VARCHAR(250), auto_series_id VARCHAR(64), user_name VARCHAR(50), release_year VARCHAR(16), release_date INTEGER, release TEXT );
-- 步骤1.1:插入数据到临时表 INSERTINTO temp_zvideo SELECTDISTINCT zc.id, zc.title, zc.auto_series_id, zc.user_name, COALESCE(zc2.release_year, zc.release_year) AS release_year, COALESCE(zc2.release_date, zc.release_date) AS release_date, COALESCE(zc2.release, zc.release) ASrelease FROM zvideo_collection zc LEFTJOIN ( SELECT auto_series_id, user_name, release_year, release_date, release FROM zvideo_collection zc2 WHERE extend_type !=7 AND release_date = ( SELECTMAX(release_date) FROM zvideo_collection zc3 WHERE zc3.auto_series_id = zc2.auto_series_id AND zc3.user_name = zc2.user_name AND zc3.extend_type !=7 AND zc3.release_date ISNOTNULL ) ) zc2 ON zc.auto_series_id = zc2.auto_series_id AND zc.user_name = zc2.user_name WHERE zc.extend_type =7;
-- 步骤2:更新原表 UPDATE zvideo_collection SET release_year =COALESCE(( SELECT release_year FROM temp_zvideo WHERE temp_zvideo.id = zvideo_collection.id ), release_year), release_date =COALESCE(( SELECT release_date FROM temp_zvideo WHERE temp_zvideo.id = zvideo_collection.id ), release_date), release=COALESCE(( SELECTrelease FROM temp_zvideo WHERE temp_zvideo.id = zvideo_collection.id ), release) WHERE id IN (SELECT id FROM temp_zvideo);
# 检查 sqlite3 命令是否可用 if ! command -v sqlite3 &> /dev/null; then log"错误:sqlite3 未安装,请先安装 sqlite3。" exit 1 fi
# 检查文件是否存在,提升脚本鲁棒性 if [ ! -f "$DB_PATH" ]; then log"错误:数据库文件 $DB_PATH 不存在。" exit 1 fi if [ ! -f "$SQL_FILE" ]; then log"错误:SQL 文件 $SQL_FILE 不存在。" exit 1 fi
log"开始更新数据库..."
# 初始化重试计数器 retry_count=0
# 使用循环处理数据库锁定情况 while [ $retry_count -lt $MAX_RETRIES ]; do # 执行 SQL 脚本,捕获输出和状态码 output=$(sqlite3 "$DB_PATH" < "$SQL_FILE" 2>&1) status=$?
# 检查执行结果 if [ $status -eq 0 ]; then log"数据库更新成功完成。更新行数:$output" break# 成功后退出循环 else # 检查是否因数据库锁定失败 ifecho"$output" | grep -q "database is locked"; then retry_count=$((retry_count + 1)) log"数据库被锁定,等待 $RETRY_INTERVAL 秒后重试... (尝试 $retry_count/$MAX_RETRIES)" sleep$RETRY_INTERVAL else log"数据库更新失败,错误信息如下:" log"$output"# 直接打印错误信息 exit 1 # 非锁定错误,直接退出 fi fi done
# 检查是否达到最大重试次数 if [ $retry_count -eq $MAX_RETRIES ]; then log"错误:达到最大重试次数 $MAX_RETRIES,数据库仍被锁定,更新失败。" exit 1 fi
# 日志函数,输出到终端和文件 log() { local level="$1" shift local message="[$level] $*" echo"$message" >&2 echo"$message" >> "$LOG_FILE" }
# 备份配置文件 backup_config() { log INFO "正在备份配置文件..." if ! sudo cp"$SSHD_CONFIG""$BACKUP_SSHD_CONFIG"; then log ERROR "备份配置文件失败" exit 1 fi log INFO "已备份到 $BACKUP_SSHD_CONFIG" }
# 检查和更新监听地址 update_listen_address() { log INFO "正在检查监听地址..." if grep -Fx "ListenAddress 0.0.0.0""$SSHD_CONFIG" >/dev/null && \ grep -Fx "ListenAddress ::""$SSHD_CONFIG" >/dev/null; then log INFO "监听地址未改动,无需修改。" return 0 fi
log INFO "监听地址需要更新" backup_config
# 使用临时文件确保修改的原子性 local temp_config temp_config=$(mktemp) if ! sed '/^ListenAddress/d'"$SSHD_CONFIG" > "$temp_config"; then log ERROR "无法处理配置文件。" rm -f "$temp_config" exit 1 fi if ! echo -e "ListenAddress 0.0.0.0\nListenAddress ::" >> "$temp_config"; then log ERROR "无法写入新监听地址。" rm -f "$temp_config" exit 1 fi if ! sudo mv"$temp_config""$SSHD_CONFIG"; then log ERROR "无法更新配置文件。" rm -f "$temp_config" exit 1 fi log INFO "已更新监听地址为 0.0.0.0 和 ::" restart_needed=true }
# 验证配置文件语法 check_config() { log INFO "正在检查 SSH 配置文件语法..." if ! sudo sshd -t >/dev/null 2>&1; then log ERROR "SSH 配置文件语法错误,请检查 $SSHD_CONFIG" # 恢复备份 if [[ -f "$BACKUP_SSHD_CONFIG" ]]; then log INFO "恢复备份配置文件" sudo mv"$BACKUP_SSHD_CONFIG""$SSHD_CONFIG" fi exit 1 fi log INFO "SSH 配置文件语法检查通过" }
# 重新加载 SSH 服务 reload_service() { log INFO "正在重新加载 SSH 服务..." if ! systemctl is-active --quiet sshd; then log ERROR "SSH 服务未运行,请检查服务状态" exit 1 fi if ! sudo systemctl reload sshd; then log ERROR "重新加载 SSH 服务失败,恢复备份" if [[ -f "$BACKUP_SSHD_CONFIG" ]]; then sudo mv"$BACKUP_SSHD_CONFIG""$SSHD_CONFIG" fi exit 1 fi log INFO "已重新加载 SSH 服务。" }
# 主逻辑 main() { # 检查 root 权限 if [[ $EUID -ne 0 ]]; then log ERROR "此脚本需要以 root 权限运行,请使用 sudo 或切换到 root 用户。" exit 1 fi
# 检查配置文件存在 if [[ ! -f "$SSHD_CONFIG" ]]; then log ERROR "SSH 配置文件 $SSHD_CONFIG 不存在。" exit 1 fi
log INFO "开始执行脚本..."
# 检查和更新监听地址 update_listen_address
# 如果需要重启,验证配置并重新加载服务 if$restart_needed; then check_config reload_service fi