Python传感器日志脚本本地正常运行 Docker中输出空或报FileNotFound错误
问题原因
两次运行异常的核心原因是两个:
- 代码路径依赖执行时的工作目录:你用
os.getcwd()拼接日志文件路径,完全依赖脚本执行时的当前工作目录,而Docker容器默认启动时的工作目录,和你手动进入容器后cd到的目录不一致:- 第一次未指定WORKDIR的Dockerfile运行时,python:3基础镜像默认工作目录为根目录
/,日志文件确实存在,但输出空字典是因为你的日志文件如果是Windows端生成的,用的是CRLF换行符,你代码中匹配数值的正则写死了(?=\n)$,无法匹配带\r的行尾,导致没有采集到任何传感器数据。 - 第二次修改Dockerfile后,你把文件复制到了
/var/env/script目录,但未指定工作目录,容器启动时工作目录还是根目录/,拼接出来的路径是//SensorLog.txt,自然找不到文件报错。你手动进入容器后先切换到了/var/env/script目录再执行脚本,工作目录符合预期,所以运行正常。
- 第一次未指定WORKDIR的Dockerfile运行时,python:3基础镜像默认工作目录为根目录
- 正则存在隐性bug:你匹配数值的正则中
.没有转义,会匹配任意字符,也可能导致部分数值匹配失败。
解决方法
方案1:修改Python代码(最稳妥,不依赖运行环境)
直接通过脚本自身路径定位日志文件,同时优化正则兼容不同换行格式,修改两处代码即可:
import os import re import statistics from collections import defaultdict def read_file(): # 替换原有的os.getcwd()逻辑,通过脚本自身路径定位日志文件 script_dir = os.path.dirname(os.path.abspath(__file__)) file_path = os.path.join(script_dir, "SensorLog.txt") reference_temp = 0 reference_humidity = 0 current_sensor_name = "" sensors = defaultdict(list) with open(file_path) as file: for row in file.readlines(): reference = re.search(r"^reference temp +(\d+\.?\d*) +humidity +(\d+\.?\d*)$", row) if reference: reference_temp = float(reference.group(1)) reference_humidity = float(reference.group(2)) current_sensor = re.search(r"^(?:(?:temperature .*)|(?:humidity .*))$", row) if current_sensor: current_sensor_name = current_sensor.group() # 优化正则:转义小数点,兼容CRLF和LF换行 value = re.search(r"(?<= )\d{1,5}\.\d{1,4}(?=\r?\n?$)", row) if value and current_sensor_name: sensors[current_sensor_name].append(value.group()) return reference_temp, reference_humidity, sensors # 剩余代码无需修改
方案2:仅修改Dockerfile(无需改代码)
显式指定容器运行时的工作目录即可,修改后的Dockerfile如下:
FROM python:3 RUN mkdir -p "/var/env/script" # 新增WORKDIR指令,指定容器运行时的默认工作目录 WORKDIR /var/env/script COPY "./sensor.py" "./SensorLog.txt" ./ ENTRYPOINT ["python3", "sensor.py"]
如果还是出现空字典的情况,可在Dockerfile中新增一行转换换行符的指令:
RUN apt update && apt install -y dos2unix && dos2unix SensorLog.txt
内容的提问来源于stack exchange,提问作者Flipscuba
相关产品推荐
相关产品推荐

