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

树莓派项目:如何在Python主脚本启停需sudo权限的子脚本?

解决方案

用subprocess模块管理子进程(推荐)

os.system无法直接控制已启动的后台进程,改用subprocess.Popen可以获取子进程对象,随时终止它:

主脚本代码

import subprocess

# 启动ringlight.py后台进程
ring_process = subprocess.Popen(["sudo", "python", "ringlight.py"])

# 需要终止补光灯时调用以下代码
# 优雅终止(推荐,给进程留清理资源的时间)
ring_process.terminate()
# 若优雅终止无效,可强制杀死进程
# ring_process.kill()

ringlight.py优化(可选)

为了让补光灯退出前能正确关闭灯光、清理NeoPixel资源,可添加信号捕获逻辑:

import signal
import sys
from rpi_ws281x import Adafruit_NeoPixel

# 初始化NeoPixel环形灯(根据你的硬件参数调整)
LED_COUNT = 16
LED_PIN = 18
strip = Adafruit_NeoPixel(LED_COUNT, LED_PIN)
strip.begin()

def cleanup_and_exit(signum, frame):
    # 关闭灯光并退出
    strip.fill(0)
    strip.show()
    sys.exit(0)

# 注册SIGTERM信号处理(对应主脚本的terminate()调用)
signal.signal(signal.SIGTERM, cleanup_and_exit)

# 补光灯运行逻辑示例(比如保持常亮)
while True:
    strip.fill((255, 255, 255))
    strip.show()

免密sudo配置(避免输入密码)

如果启动时需要手动输入sudo密码,可配置免密权限简化操作:

  1. 执行sudo visudo
  2. 在文件末尾添加一行(替换为你的实际文件路径):
    pi ALL=(ALL) NOPASSWD: /usr/bin/python /home/pi/ringlight.py
    

替代方案:文件信号控制

如果不想用信号机制,可通过临时文件作为终止标记:

ringlight.py代码

import os
import sys
import time
from rpi_ws281x import Adafruit_NeoPixel

strip = Adafruit_NeoPixel(16, 18)
strip.begin()

TERM_MARKER = "/tmp/ringlight_stop"
# 清除旧的终止标记
if os.path.exists(TERM_MARKER):
    os.remove(TERM_MARKER)

while True:
    if os.path.exists(TERM_MARKER):
        # 清理灯光并退出
        strip.fill(0)
        strip.show()
        os.remove(TERM_MARKER)
        sys.exit(0)
    # 补光灯运行逻辑
    strip.fill((255, 255, 255))
    strip.show()
    time.sleep(0.1)

主脚本终止代码

# 创建终止标记文件触发退出
open("/tmp/ringlight_stop", "w").close()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 13:18:32