You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Linux下os.replace原子替换异常:Signal 15导致JSON日志损坏

问题原因及修复方案

核心原因

你的问题出在两个关键环节:

  • 临时文件使用追加模式写入:代码里用'a+'打开临时文件,这种模式不会覆盖已有内容,只会在末尾追加。如果之前某次操作因Signal 15中断,临时文件残留了未写完的不完整JSON(比如缺闭合括号),下次启动时新的完整JSON会直接追加到这个残缺文件后面,最终替换原日志后就出现了内容叠加的情况。
  • Signal 15未被处理,写入过程被强制终止:Signal 15(SIGTERM)默认会直接终止进程,要是刚好赶上json.dump正在写入临时文件,进程会立刻停掉,导致临时文件内容不完整。而你的代码没有提前清理临时文件,也没确保写入完成,残留的残缺文件就会被后续操作复用。

修复方法

1. 改用覆盖模式写入临时文件

把打开临时文件的模式从'a+'改成'w',这样每次都会重新创建/覆盖临时文件,彻底避免残留内容的影响:

with open(temp_file_name, 'w') as f:
    json.dump(existing, f, indent=2, default=vars)

2. 用唯一临时文件避免复用问题

推荐使用Python标准库的tempfile生成唯一临时文件,从根源上杜绝重复使用同一个临时文件的可能:

import tempfile
import os

# 在日志文件所在目录生成唯一临时文件,避免跨文件系统替换问题
with tempfile.NamedTemporaryFile(mode='w', delete=False, dir=os.path.dirname(log_file_path)) as tmp_file:
    json.dump(existing, tmp_file, indent=2, default=vars)

# 原子替换原日志
os.replace(tmp_file.name, log_file_path)
# 替换成功后清理临时文件,防止意外残留
os.unlink(tmp_file.name)

3. 处理Signal 15,保证写入完成

注册信号处理函数,让进程收到SIGTERM时先完成当前写入操作再退出,避免中途被强制终止:

import signal
import sys

def sigterm_handler(signum, frame):
    # 这里可以添加必要的收尾逻辑,确保当前写入操作完成
    sys.exit(0)

# 注册SIGTERM信号处理
signal.signal(signal.SIGTERM, sigterm_handler)

内容的提问来源于stack exchange,提问作者Sascha Lüthi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 14:30:59