重启脚本仅终止lxterminal进程无法重新拉起业务程序故障排查
条码扫描程序定时重启故障排查
问题概述
- 业务目标:开发条码扫描处理程序,实现指定时长内未接收到条码扫描输入时,自动终止当前运行程序并重启的逻辑
- 故障现象:验证定时重启逻辑时,脚本仅能终止现有运行程序,无法完成后续程序启动操作,全程无错误码返回
- 初步判断:故障点位于
barcoderestart.sh与starttimer.py的交互逻辑,其余模块运行符合预期
现有相关代码
1. 终止终端并重启程序的barcoderestart.sh脚本
#!/bin/bash pkill -f lxterminal sleep 1 pkill -f lxterminal sync sleep 5 export DISPLAY=:0.0 lxterminal -e /home/nvidia/local_orch/utilities/barcodetest.sh & sleep 5
2. barcoderestart.sh调用的业务入口barcodetest.sh脚本
#!/bin/bash cd /home/nvidia/local_orch/utilities python3 ./barcodetest.py
3. 核心业务逻辑barcodetest.py脚本
def writeLog(l): lt = time.localtime(time.time()) global insstarttime insstarttime = lt lt2 = str(lt[0])+"-"+str(lt[1])+"-"+str(lt[2])+"-"+str(lt[3])+"."+str(lt[4])+"."+str(lt[5]) lg = lt2+" : "+l with open('barcodetest.txt','a') as lfile: lfile.write(lg+"\n") print(lg) return 0 while not stopped: mins, secs = divmod(t, 60) timer = '{:02d}:{:02d}'.format(mins, secs) print(timer, end="\r") time.sleep(1) t -= 1 print('Fire in the hole!!') while True: lt = time.localtime(time.time()) rawscan = '' while sys.stdin in select.select([sys.stdin],[],[],0)[0]: input0 = sys.stdin.readline() if input0: rawscan = input0.rstrip() PN = rawscan[0:7] serial = rawscan[8:] serial = serial.strip() print("Part number is "+PN) print("serial is "+ serial) writeLog("RAW Scan is "+rawscan) os.system("lxterminal -e /home/nvidia/local_orch/utilities/timer.sh")
4. 扫描触发后启动的timer.sh脚本
#!/bin/bash cd /home/nvidia/local_orch/utilities python3 ./starttimer.py
5. 负责倒计时触发重启的starttimer.py脚本
def countdown(t): while t: mins, secs = divmod(t, 60) timer = '{:02d}:{:02d}'.format(mins, secs) print(timer, end="\r") time.sleep(1) t -= 1 print('Fire in the hole!!') countdown(int(5)) time.sleep(1) os.system("/home/nvidia/local_orch/utilities/barcoderestart.sh")
故障根因
- 进程误杀导致重启脚本中途终止:
barcoderestart.sh使用pkill -f lxterminal无差别匹配所有命令行带lxterminal的进程,包括运行重启脚本本身的父终端进程。父进程被杀后,重启脚本会收到SIGHUP信号直接退出,根本执行不到后续启动新业务终端的步骤。就算新终端提前启动,也会被宽泛的匹配规则一起杀掉。 - 进程未脱离终端控制:
starttimer.py直接调用重启脚本时,脚本属于当前lxterminal的子进程,没有脱离原终端进程组,原终端退出时脚本会被连带终止。 - 代码存在冗余死代码与语法隐患:
barcodetest.py中writeLog函数return语句后的while循环永远不会执行;starttimer.py中countdown函数存在缩进不统一问题,容易触发语法错误;所有脚本未做异常日志输出,出错后无任何提示,排查困难。
修复方案
1. 改造barcoderestart.sh杀进程逻辑,精准匹配业务进程
替换宽泛的全量lxterminal杀除规则,只杀业务相关进程,同时确保重启脚本脱离终端控制,修改后代码如下:
#!/bin/bash # 精准杀掉业务相关进程,避免误杀 pkill -f "barcodetest.sh" pkill -f "timer.sh" pkill -f "barcodetest.py" pkill -f "starttimer.py" sleep 1 # 二次强杀确保残留进程退出 pkill -9 -f "barcodetest.py" pkill -9 -f "starttimer.py" sync sleep 2 export DISPLAY=:0.0 # 启动新业务终端,输出重定向到空避免挂死 nohup lxterminal -e /home/nvidia/local_orch/utilities/barcodetest.sh > /dev/null 2>&1 & sleep 3
2. 改造starttimer.py调用逻辑,让重启脚本脱离原终端
调用重启脚本时使用nohup挂起,同时修复缩进问题、补全缺失的依赖导入,修改后代码如下:
import time import os def countdown(t): while t: mins, secs = divmod(t, 60) timer = '{:02d}:{:02d}'.format(mins, secs) print(timer, end="\r") time.sleep(1) t -= 1 print('Fire in the hole!!') countdown(int(5)) time.sleep(1) # nohup启动重启脚本,输出写入日志方便排查,脱离当前终端进程组 os.system("nohup /home/nvidia/local_orch/utilities/barcoderestart.sh > /tmp/barcode_restart.log 2>&1 &")
3. 清理barcodetest.py死代码
删除writeLog函数return 0之后永远无法执行的while循环代码块,避免后续维护混淆。
4. 统一配置脚本权限
执行以下命令给所有业务脚本添加可执行权限,避免权限不足导致启动失败:
chmod +x /home/nvidia/local_orch/utilities/*.sh chmod +x /home/nvidia/local_orch/utilities/*.py
内容的提问来源于stack exchange,提问作者Daniel
相关产品推荐
相关产品推荐

