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

如何关闭脚本外打开的.csv文件?树莓派Python RFID门锁日志问题

解决CSV文件被占用导致Python脚本无法写入的问题

嘿,我来帮你搞定这个麻烦事!在Raspbian OS上,当LibreOffice打开着你的日志CSV文件时,文件会被对应的进程锁定,导致Python脚本没法写入。咱们可以通过找到并终止占用文件的进程来解决这个问题,下面是具体的实现方法:

方法一:通用型解决方案(用lsof定位所有占用进程)

lsof是Linux下专门用来查看哪些进程打开了哪些文件的工具,先确保它已经安装:

sudo apt-get install lsof

接下来可以在Python脚本里集成这段逻辑,自动关闭所有占用目标CSV的进程:

import os
import subprocess
import time

def close_open_csv(csv_filename):
    """关闭所有占用指定CSV文件的进程"""
    try:
        # 调用lsof获取占用文件的进程ID列表
        pid_output = subprocess.check_output(
            ["lsof", "-t", "-f", "--", csv_filename],
            stderr=subprocess.STDOUT,
            text=True
        )
        pids = [pid.strip() for pid in pid_output.split('\n') if pid.strip()]
        
        if not pids:
            print(f"[{csv_filename}] 当前没有被其他进程占用")
            return
        
        # 先尝试正常终止进程(信号15),失败再强制终止(信号9)
        for pid in pids:
            try:
                os.kill(int(pid), 15)
                print(f"尝试正常终止进程 {pid}...")
                # 等待1秒让进程处理关闭
                time.sleep(1)
                # 检查进程是否还在运行
                os.kill(int(pid), 0)
                # 如果走到这里说明进程还在,强制终止
                os.kill(int(pid), 9)
                print(f"进程 {pid} 已被强制终止")
            except OSError:
                # 进程已经关闭,跳过
                print(f"进程 {pid} 已正常关闭")
    except subprocess.CalledProcessError as e:
        if e.returncode == 1:
            print(f"[{csv_filename}] 未找到占用进程")
        else:
            print(f"查找进程时出错:{e.output}")

# 使用示例:假设你的日志文件是door_access_log.csv
log_file = "door_access_log.csv"
# 先关闭占用进程
close_open_csv(log_file)
# 再执行写入操作
try:
    with open(log_file, 'a', newline='', encoding='utf-8') as f:
        # 这里替换成你的日志写入逻辑,比如记录时间、RFID卡号等
        f.write("2024-05-20 14:30:00, RFID_12345, 进门成功\n")
    print("日志写入成功")
except Exception as e:
    print(f"写入失败:{str(e)}")

方法二:针对LibreOffice的专属处理

因为你明确是LibreOffice打开了CSV,也可以直接定位LibreOffice的后台进程(一般是soffice.bin),更精准地关闭对应的实例:

import subprocess

def close_libreoffice_csv(csv_filename):
    """关闭打开指定CSV的LibreOffice进程"""
    try:
        # 查找打开目标CSV的soffice.bin进程
        lsof_result = subprocess.check_output(
            ["lsof", "-c", "soffice.bin", "--", csv_filename],
            stderr=subprocess.STDOUT,
            text=True
        )
        lines = lsof_result.strip().split('\n')
        # 第一行是表头,从第二行开始提取PID
        if len(lines) > 1:
            pid = lines[1].split()[1]
            # 先尝试正常终止
            subprocess.run(["kill", "-15", pid], check=True)
            print(f"打开[{csv_filename}]的LibreOffice进程已正常关闭")
        else:
            print(f"LibreOffice没有打开[{csv_filename}]")
    except subprocess.CalledProcessError as e:
        if e.returncode == 1:
            print(f"未找到打开[{csv_filename}]的LibreOffice进程")
        else:
            print(f"处理出错:{e.output}")

# 使用示例
close_libreoffice_csv("door_access_log.csv")

额外小贴士

  1. 权限问题:如果脚本运行时提示权限不足,可以尝试用sudo运行脚本,或者确保LibreOffice是当前用户启动的(一般都是)。
  2. 异常重试:可以在写入逻辑里加个重试机制,当捕获到PermissionError时自动调用关闭函数,再重试写入,这样更健壮。
  3. 尽量避免强制终止:用信号15(正常终止)给LibreOffice机会保存文件,只有当正常终止失败时再用信号9(强制终止)。

内容的提问来源于stack exchange,提问作者Kevin Coleman

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 04:28:05