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

为何通过/etc/profile autorun的Python MQTT脚本无法稳定连接Broker?

MQTT脚本手动运行正常,开机自启(/etc/profile)时无限断连重连的解决办法

最近折腾一个控制多LED的Python脚本,用到MQTT和Broker通信,手动在Shell里跑完全没问题,MQTT连接稳得一批;但想着让它开机自动启动,把命令sudo python3 /home/pi/..../main.py &加到/etc/profile里后,脚本倒是能启动,可MQTT连接就疯了——无限循环断开、重连,Broker端反复收到RPiGiulio/Connection/status的0和1状态,根本没法稳定工作。

先贴一下我脚本里MQTT连接相关的代码:

def Connect(client,broker,port,keepalive,run_forever=False):
    connflag=False
    delay=5
    print('--------------------------------')
    print("connecting " + client_id)
    badcount=0 # counter for bad connection attempts
    while not connflag:
        logging.info("connecting to broker "+str(broker))
        print("connecting to broker "+str(broker)+":"+str(port))
        print("Attempts ",badcount)
        try:
            res=client.connect(broker,port,keepalive) #connect to broker
            if res==0:
                print('--------------------------------')
                print("Connection established")
                print('--------------------------------')
                connflag=True
                return 0
            else:
                logging.debug("connection failed.")
                print('--------------------------------')
                badcount += 1
                if badcount>=3 and not run_forever:
                    raise SystemExit #give up
                elif run_forever and badcount<3:
                    delay=5
                else:
                    delay=3

def on_connect(client, userdata, flags, rc):
    print('--------------------------------')
    logging.debug("Connected flags"+str(flags)+"result code " + str(rc) + "client RPi Giulio")
    if rc == 0:
        print("Connected OK. Returned code = ", rc)
        print('--------------------------------')
        client.connected_flag = True
        client.publish(connected_topic,1,retain=True)
    else:
        print("Bad connection. Returned code = ", rc)
        print('--------------------------------')
        client.bad_connection_flag = True

Broker那边的状态日志就是反复跳:

RPiGiulio/Connection/status 0
RPiGiulio/Connection/status 1
RPiGiulio/Connection/status 0
RPiGiulio/Connection/status 1
...(无限循环)

踩坑后的分析

后来查了下,/etc/profile是用户登录时触发的脚本,它的执行环境和手动开Shell跑脚本差不少:

  • 环境变量不全:比如PATH或者脚本依赖的一些配置变量可能没加载全,导致连接Broker时出隐性错误
  • 网络没准备好:/etc/profile执行的时候,系统可能还在初始化网络,这时候脚本去连Broker肯定失败,后续重连也因为环境问题稳不住
  • 权限上下文不对:用sudo在/etc/profile里跑脚本,用户环境和手动执行时不一样,也可能引发连接异常

亲测有效的解决办法:改用Crontab

放弃/etc/profile那套,换成crontab来做开机自启,步骤超简单:

  1. 打开crontab的编辑界面:
    crontab -e
    
  2. 在文件最后加一行,指定开机启动你的脚本:
    @reboot sudo python3 /home/pi/你的脚本实际路径/main.py &
    
  3. 保存退出就行,crontab会自动生效

这样配置后,系统会等所有初始化(包括网络)都完成后再执行脚本,MQTT连接就能稳定建立了,完美解决之前的断连循环问题。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 07:28:00