使用sudo运行含ping3的Python脚本立即退出的原因及解决方案咨询
问题描述
我编写了一个使用ping3库执行服务器ping检测的Python脚本,由于该功能需要root权限,因此用sudo运行。但发现不使用sudo时脚本可正常保持运行状态,使用sudo运行则立即退出且无任何异常抛出。脚本代码如下:
import atexit import RPi.GPIO as gpio import sys import time from threading import Thread import ping3 from ping3 import ping from phue import Bridge from datetime import datetime ping3.EXCEPTIONS = False functionOne = 13 functionTwo = 15 functionThree = 16 relaisStörung = 18 functionOneState = False functionTwoState = False errorState = False def handleExit(): gpio.cleanup() print('EXITED! ', hueLogic.getCurrentDateTime()) sys.exit(0) class NetworkWatchdog(Thread): def __init__(self): # Call the Thread class's init function Thread.__init__(self) def run(self): global errorState routerAddress = '192.168.178.1' errorCounter = 0 while 1: result = ping(routerAddress) if not result or result is None: errorCounter = + 1 else: errorCounter = 0 if errorCounter > 1: print('Netzwerk Fehler! Stör Relay an! ', hueLogic.getCurrentDateTime()) errorState = True gpio.output(relaisStörung, gpio.HIGH) elif errorCounter < 1: if errorState: print("Netzwerk Fehler behoben! Stör Relay normal! ", hueLogic.getCurrentDateTime()) errorState = False gpio.output(relaisStörung, gpio.LOW) time.sleep(2) # sys.stdout = open('/home/admin/Desktop/log.log', 'a+') # sys.stderr = open('/home/admin/Desktop/log.log', 'a+') atexit.register(handleExit) hueLogic = HueLogic() watchDog = NetworkWatchdog() watchDog.daemon = True watchDog.start() print("--------------------------------") print("Programm started! ", hueLogic.getCurrentDateTime()) gpio.setmode(gpio.BOARD) gpio.setup(functionOne, gpio.IN, pull_up_down=gpio.PUD_DOWN) gpio.setup(functionTwo, gpio.IN, pull_up_down=gpio.PUD_DOWN) gpio.setup(functionThree, gpio.IN, pull_up_down=gpio.PUD_DOWN) gpio.setup(relaisStörung, gpio.OUT) # relais default on gpio.output(relaisStörung, gpio.LOW) gpio.add_event_detect(functionOne, gpio.BOTH, callback=hueLogic.functionOne, bouncetime=500) gpio.add_event_detect(functionTwo, gpio.BOTH, callback=hueLogic.functionTwo, bouncetime=500) gpio.add_event_detect(functionThree, gpio.BOTH, callback=hueLogic.functionThree, bouncetime=500)
现咨询该现象产生的原因,以及添加while True循环作为解决方案是否可行?
问题分析与解决方案
一、现象原因
核心问题出在守护线程特性和sudo环境下主线程的退出时机:
- 你将
watchDog线程设为了守护线程(watchDog.daemon = True),这类线程的规则是:当所有非守护线程结束时,Python进程会直接终止,不管守护线程是否还在运行。 - 不使用sudo时,RPi.GPIO的
add_event_detect会依赖底层系统事件循环让主线程保持活跃,不会立即退出,因此守护线程能正常运行。 - 使用sudo时,权限上下文或环境变量的变化,导致RPi.GPIO的事件检测无法维持主线程的阻塞状态,主线程执行完所有初始化代码后直接退出,守护线程被强制终止,进程随之结束,所以看不到异常——进程是被正常终止的。
另外代码里存在一个小bug:errorCounter = + 1应该写成errorCounter += 1,否则每次错误只会把计数器设为1,无法累加,会导致网络故障判断逻辑失效。
二、添加while True循环是否可行?
完全可行,这是解决该问题的简单有效方案:
- 在脚本末尾添加如下代码,让主线程保持阻塞状态,不会提前退出,守护线程就能持续运行:
while True: time.sleep(1) - 另一种替代方案是把
watchDog.daemon设为False,这样即使主线程结束,只要该线程还在运行,进程就不会终止。不过这种方式需要注意线程的优雅退出逻辑,避免进程无法正常结束。
额外建议
- 修复
errorCounter = +1的bug,改为errorCounter +=1,确保网络故障计数逻辑正常工作。 - 开启日志输出到文件的代码(你已注释的部分),方便排查sudo运行时的潜在问题,比如是否能正常加载
phue库或访问GPIO引脚。
内容的提问来源于stack exchange,提问作者Dahlin
相关产品推荐
相关产品推荐

