如何在Docker容器的Python脚本中用环境变量解析起止时间
用环境变量配置OLED显示时段的解决方案
问题背景
当前Python脚本运行在Docker容器中,原本硬编码了8:30至23:00的显示时段,希望通过Docker环境变量调整该时段(无需进入容器修改代码或挂载配置卷)。但尝试将8, 30, 0作为名为start的环境变量解析时遇到问题:直接使用字符串无法处理,转换为int时触发ValueError(invalid literal for int() with base 10: '8, 30, 0')。需要实现支持用户指定**时、分(秒可选)**的起止时间方案。
实现步骤
- 导入
os模块读取Docker环境变量 - 编写时间解析函数,将环境变量的逗号分隔字符串转换为
datetime.time对象,自动补全缺失的秒数为0 - 保留原硬编码值作为默认值,确保未设置环境变量时脚本仍正常运行
修改后的完整代码
#!/usr/bin/env python3 # For Raspberry Pi Desktop Case with OLED Stats Display # Base on Adafruit CircuitPython & SSD1306 Libraries import os import time import board import busio import digitalio import adafruit_ssd1306 import subprocess import datetime from time import sleep from PIL import Image, ImageDraw, ImageFont def time_in_range(start, end, current): # 判断当前时间是否在[start, end]区间内 return start <= current <= end def parse_time_env(env_str, default_hour, default_minute, default_second=0): """解析环境变量中的时间字符串,格式支持"时,分"或"时,分,秒",返回datetime.time对象""" if not env_str: return datetime.time(default_hour, default_minute, default_second) parts = list(map(int, env_str.strip().split(','))) hour = parts[0] if len(parts) >=1 else default_hour minute = parts[1] if len(parts) >=2 else default_minute second = parts[2] if len(parts) >=3 else default_second return datetime.time(hour, minute, second) # Display Parameters width = 128 height = 64 # Font size font_sz = 16 # 从环境变量读取起止时间,未设置则用默认值 start = parse_time_env(os.getenv('START_TIME'), 8, 30, 0) end = parse_time_env(os.getenv('END_TIME'), 23, 0, 0) current = datetime.datetime.now().time() # 初始化OLED显示屏 oled = adafruit_ssd1306.SSD1306_I2C(width, height, board.I2C(), addr=0x3C, reset=digitalio.DigitalInOut(board.D4)) # 清空显示屏 oled.fill(0) oled.show() # 创建用于绘制的空白图像(1位颜色) image = Image.new('1', (oled.width, oled.height)) # 获取绘图对象 draw = ImageDraw.Draw(image) # 导入自定义字体 font = ImageFont.truetype('PixelOperator.ttf', font_sz) icon_font= ImageFont.truetype('lineawesome-webfont.ttf', font_sz) while True: while (time_in_range(start, end, current)): current = datetime.datetime.now().time() draw.rectangle((0, 0, oled.width, oled.height), fill=0) # 绘制黑色填充框清空图像 cmd = "ip addr | awk '/inet / { print $2 }' | sed -n '2{p;q}' | cut -d '/' -f1" IP = subprocess.check_output(cmd, shell = True ) cmd = "vmstat 4 2|tail -1|awk '{print 100-$15}' | tr -d '\n'" CPU = subprocess.check_output(cmd, shell = True ) cmd = "free -m | awk 'NR==2{printf $3}'| awk '{printf $1/1000}'" Memuse = subprocess.check_output(cmd, shell = True ) cmd = "cat /proc/meminfo | head -n 1 | awk -v CONVFMT='%.0f' '{printf $2/1000000}'" MemTotal = subprocess.check_output(cmd, shell = True ) cmd = "free -m | awk -v CONVFMT='%.1f' 'NR==2{printf $3*100/$2}'" Memuseper = subprocess.check_output(cmd, shell = True ) cmd = "df -h | awk '$NF==\"/\"{printf \"%s\", $5}'" Disk = subprocess.check_output(cmd, shell = True ) cmd = "uptime | awk '{print $3,$4}' | cut -f1 -d','" uptime = subprocess.check_output(cmd, shell = True ) cmd = "cat /sys/class/thermal/thermal_zone*/temp | awk -v CONVFMT='%.1f' '{printf $1/1000}'" temp = subprocess.check_output(cmd, shell = True ) # 绘制图标 draw.text((1, 0), chr(61931), font=icon_font, fill=255) draw.text((1, 16), chr(62171), font=icon_font, fill=255) draw.text((111, 16), chr(62153), font=icon_font, fill=255) draw.text((1, 32), chr(62776), font=icon_font, fill=255) draw.text((1, 48), chr(63426), font=icon_font, fill=255) draw.text((111, 48), chr(62034), font=icon_font, fill=255) # 绘制系统状态文本 draw.text((22, 0), str(IP,'utf-8'), font=font, fill=255) draw.text((22, 16), str(CPU,'utf-8') + "%", font=font, fill=255) draw.text((107, 16), str(temp,'utf-8') + "°C", font=font, fill=255, anchor="ra") draw.text((22, 32), str(Memuseper,'utf-8') + "%", font=font, fill=255) draw.text((125, 32), str(Memuse,'utf-8') + "/" + str(MemTotal,'utf-8') + "G", font=font, fill=255, anchor="ra") draw.text((22, 48), str(Disk,'utf-8'), font=font, fill=255) draw.text((107, 48), str(uptime,'utf-8'), font=font, fill=255, anchor="ra") # 显示图像 oled.image(image) oled.show() time.sleep(0) else: oled.fill(0) oled.show() sleep(60) current = datetime.datetime.now().time()
使用说明
运行Docker容器时,通过-e参数传递环境变量即可调整显示时段:
- 指定开始时间(仅时分):
docker run -e *START_TIME*="9,0" ... - 指定结束时间(包含秒):
docker run -e *END_TIME*="22,30,0" ... - 同时指定起止时间:
docker run -e *START_TIME*="7,45" -e *END_TIME*="23,15" ...
如果不传递环境变量,脚本会默认使用原有的8:30至23:00时段。
内容的提问来源于stack exchange,提问作者Macley
相关产品推荐
相关产品推荐

