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

如何修复Systemd启动Python脚本时的IndexError: list index out of range错误

问题描述

原本正常运行的OLED脚本,添加随机运行Luma Examples脚本的功能后,通过systemd启动时出现报错,但在Geany中运行正常。

初始错误日志

crawl_oled.service - test OLED SSD1306
     Loaded: loaded (/lib/systemd/system/crawl_oled.service; enabled; vendor preset: enabled)
     Active: failed (Result: exit-code) since Wed 2024-03-06 08:30:14 EST; 2min 33s ago
    Process: 200235 ExecStartPre=/bin/sleep 30 (code=exited, status=0/SUCCESS)
    Process: 200600 ExecStart=/usr/bin/python3 /home/pi/luma-env/luma.examples/examples/OLED_INFO.py (code=exited, status=1/FAILURE)
   Main PID: 200600 (code=exited, status=1/FAILURE)
        CPU: 609ms

Mar 06 08:30:14 raspberrypi python3[200600]: Traceback (most recent call last):
Mar 06 08:30:14 raspberrypi python3[200600]:   File "/home/pi/luma-env/luma.examples/examples/OLED_INFO.py", line 299, in <module>
Mar 06 08:30:14 raspberrypi python3[200600]:     run_ext()
Mar 06 08:30:14 raspberrypi python3[200600]:   File "/home/pi/luma-env/luma.examples/examples/OLED_INFO.py", line 59, in run_ext
Mar 06 08:30:14 raspberrypi python3[200600]:     random_py = random.choice(Local_List)
Mar 06 08:30:14 raspberrypi python3[200600]:   File "/usr/lib/python3.9/random.py", line 347, in choice
Mar 06 08:30:14 raspberrypi python3[200600]:     return seq[self._randbelow(len(seq))]
Mar 06 08:30:14 raspberrypi python3[200600]: IndexError: list index out of range
Mar 06 08:30:14 raspberrypi systemd[1]: crawl_oled.service: Main process exited, code=exited, status=1/FAILURE
Mar 06 08:30:14 raspberrypi systemd[1]: crawl_oled.service: Failed with result 'exit-code'.

系统信息

pi@raspberrypi:~ $ cat /etc/os-release
PRETTY_NAME="Debian GNU/Linux 11 (bullseye)"
NAME="Debian GNU/Linux"
VERSION_ID="11"
VERSION="11 (bullseye)"
VERSION_CODENAME=bullseye
ID=debian
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"

问题代码片段

def run_ext():
    i = 0
    while True:
        try:
            # Command to run "OTHER".py
            ####random_file=random.choice(os.listdir())
            Local_List = [each for i, each in enumerate(os.listdir(current_working_directory)) if each.endswith('1.py')]
            random_py = random.choice(Local_List)
            random_py = current_working_directory + '/' + str(random_py)
            print(random_py)
            sp.run(random_py, timeout=10)
        except sp.TimeoutExpired:
            break 

修改后的错误日志

修改为random_py = random.choice(Local_List[i])后,报错如下:

crawl_oled.service - test OLED SSD1306
     Loaded: loaded (/lib/systemd/system/crawl_oled.service; enabled; vendor preset: enabled)
     Active: failed (Result: exit-code) since Wed 2024-03-06 08:52:57 EST; 2s ago
    Process: 216809 ExecStartPre=/bin/sleep 30 (code=exited, status=0/SUCCESS)
    Process: 217172 ExecStart=/usr/bin/python3 /home/pi/luma-env/luma.examples/examples/OLED_INFO.py (code=exited, status=1/FAILURE)
   Main PID: 217172 (code=exited, status=1/FAILURE)
        CPU: 545ms

Mar 06 08:52:56 raspberrypi systemd[1]: Started test OLED SSD1306.
Mar 06 08:52:57 raspberrypi python3[217172]: /
Mar 06 08:52:57 raspberrypi python3[217172]: Traceback (most recent call last):
Mar 06 08:52:57 raspberrypi python3[217172]:   File "/home/pi/luma-env/luma.examples/examples/OLED_INFO.py", line 299, in <module>
Mar 06 08:52:57 raspberrypi python3[217172]:     run_ext()
Mar 06 08:52:57 raspberrypi python3[217172]:   File "/home/pi/luma-env/luma.examples/examples/OLED_INFO.py", line 59, in run_ext
Mar 06 08:52:57 raspberrypi python3[217172]:     random_py = random.choice(Local_List[i])
Mar 06 08:52:57 raspberrypi python3[217172]: IndexError: list index out of range
Mar 06 08:52:57 raspberrypi systemd[1]: crawl_oled.service: Main process exited, code=exited, status=1/FAILURE
Mar 06 08:52:57 raspberrypi systemd[1]: crawl_oled.service: Failed with result 'exit-code'.

需求

实现从Luma Examples文件夹中随机选择一个示例运行10秒,然后继续执行main()的剩余部分。


解决方案

核心问题分析

报错IndexError: list index out of range的根本原因是**Local_List为空**:

  • systemd服务默认工作目录是根目录/,如果current_working_directory依赖相对路径或os.getcwd()获取,会指向根目录,而根目录下没有符合*.1.py的文件。
  • Geany运行时工作目录是脚本所在的/home/pi/luma-env/luma.examples/examples/,所以能正常找到文件。

修复步骤

  1. 固定脚本目录路径:直接使用脚本所在的绝对路径定位目标文件夹,不依赖当前工作目录。
  2. 添加空列表判断:避免无符合条件文件时触发报错。
  3. 修正random.choice用法:该函数接收列表本身,不需要额外索引。

修复后的代码

import os
import random
import subprocess as sp

def run_ext():
    # 获取当前脚本所在的绝对目录
    script_dir = os.path.dirname(os.path.abspath(__file__))
    # 筛选所有以1.py结尾的文件
    local_list = [f for f in os.listdir(script_dir) if f.endswith('1.py')]
    
    # 判断列表是否为空,提前返回避免报错
    if not local_list:
        print("未找到符合条件的.py文件")
        return
    
    # 随机选择一个文件并拼接完整路径
    random_py = random.choice(local_list)
    random_py_path = os.path.join(script_dir, random_py)
    
    try:
        print(f"运行脚本: {random_py_path}")
        # 运行脚本10秒后超时退出
        sp.run(["python3", random_py_path], timeout=10)
    except sp.TimeoutExpired:
        print("脚本运行超时,结束执行")
    # 执行完成后自动返回,继续main()剩余逻辑

额外优化

如果systemd服务仍有异常,可以在crawl_oled.service配置中指定工作目录:

[Service]
WorkingDirectory=/home/pi/luma-env/luma.examples/examples/
ExecStart=/usr/bin/python3 /home/pi/luma-env/luma.examples/examples/OLED_INFO.py

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 19:43:17