记一次完整的rc.local中启动python脚本报psutil找不到问题解决

news2024/9/21 16:30:40

文章目录

  • 1,问题
    • 1.1,rc.local
    • 1.2,watchdog.py
  • 2,问题排查
    • 2.1,手动执行start.sh后功能正常
    • 2.2,开机启动后rc.local加载start.sh,然后start.sh启动python脚本报错
    • 2.3,怀疑是rc.local加载的时候,python脚本中用到的psutil模块还没加载
  • 3,方案一:让start.sh脚本后台运行,直到watchdog.py执行成功后才退出
    • 3.1,start.sh脚本中最多重试5次后退出,间隔5秒
    • 3.2,但开机启动后,发现返回了脚本执行成功,然后才打印了watchdog.py中报错
    • 3.3,那么是不是会是nohup使start.sh脚本忽略了watchdog.py启动时的异常呢
    • 3.4,去除nohup后,报错依旧,仍然不成功
  • 4,方案二:不使用返回值而采用判断进程是否存
    • 4.1,start.sh脚本如下所示
    • 4.1,开机启动后,返现仍然无法启动watchdog.py,仍然报错psutil找不到
    • 4.2,发现rc.local启动后的start.sh脚本进程属于root用户
    • 4.3,而手动启动后的start.sh脚本进程属于username用户
    • 4.4,那么有没有可能就是由于启动start.sh脚本的用户不同,一个有psutil模块,一个没有导致的失败呢?
      • 4.4.1,开机后rc.local脚本启动start.sh脚本,打印用户名是root
      • 4.4.2,手动启动start.sh脚本,打印用户名是当前username
      • 4.4.3,如果想要跟踪脚本运行的命令对不对,可以使用exec 1>>file和set -x
  • 5,方案三:指定启动watchdog.sh的用户
    • 5.1,修改start.sh脚本如下所示
    • 5.2,重启电脑后发现完美解决了

1,问题

场景是windos10开机后在其ubuntu子系统中启动其他服务。
在ubuntu子系统rc.local脚本中启动shell脚本没问题,但是启动python脚本却会失败,会报某模块找不到
百度查到说是由于rc.local脚本的执行顺序先于python脚本的依赖库造成的

2023-04-20 00:46:08.1681922768 import error: No module named ‘psutil’

1.1,rc.local

#!/bin/bash -x

LOG_FILE="/mnt/e/111111111/package/log/rc.local.log"

exec 1>> $LOG_FILE 2>&1
set -x

echo password|sudo -S /etc/init.d/apache2 restart

TIMES=`date +"%Y-%m-%d %H:%M:%S.%3N"`
echo "$TIMES /etc/rc.local start apache2" >> $LOG_FILE

cd /xxxxx/package
nohup ./start.sh >> $LOG_FILE 2>&1 &

TIMES=`date +"%Y-%m-%d %H:%M:%S.%3N"`
echo "$TIMES /etc/rc.local start start.sh" >> $LOG_FILE

exit 0

1.2,watchdog.py

import subprocess
import time
import psutil
import setproctitle
# 重命名进程名
setproctitle.setproctitle("watchdog.py")

def checkProcess(process_name):
    for process in psutil.process_iter():
        if process.name() == process_name:
            return True
    return False

def killProcess(process_name):
    for process in psutil.process_iter():
        if process.name() == process_name:
            process.kill()
def startProces(path, program):
    param = [path + "/"+ program]
    if checkProcess(program):
        killProcess(program)
        print("{} is existed and has been killed! it will be resatrt for a moment!".format(program))

    process = subprocess.Popen(param)
    print("{} started! process[{}]".format(program, process))
    return process

def run(path, program):
    process = startProces(path, program)
    while True:
        time.sleep(5)  # 检查每隔60秒
        if process.poll() is not None:  # 检查进程是否崩溃
            process = startProces(path, program)
        else:     
            print("{} is running".format(program))

if __name__ == '__main__':
    run("server", "webserver")

2,问题排查

为了方便问题解决更加方便,我准备了一个shell脚本start.sh,在rclocal中启动start.sh,在start.sh中启动python脚本。

在这里插入图片描述

#!/bin/bash

LOG_FILE="/mnt/e/package/log/start.log"

LOG()
{
	TIMES=`date +"%Y-%m-%d %H:%M:%S.%3N"`
	echo "${TIMES}$1" >> $LOG_FILE
}

cd /mnt/e/package
nohup python3 watchdog.py >> $LOG_FILE 2>&1 &
LOG "EXECUTE_CMD /mnt/e/package python3 watchdog.py. result:$?"

exit $?

2.1,手动执行start.sh后功能正常

在这里插入图片描述
start.log中如下所示

2023-04-20 19:37:26.780 EXECUTE_CMD /mnt/e/package python3 watchdog.py. result:0

2.2,开机启动后rc.local加载start.sh,然后start.sh启动python脚本报错

wangdog进程和webserver进程都没起来,start.log中如下所示

2023-04-22 02:06:06.082EXECUTE_CMD /mnt/e/package python3 watchdog.py. result:0
Traceback (most recent call last):
  File "/mnt/e/package/watchdog.py", line 3, in <module>
    import psutil
ModuleNotFoundError: No module named 'psutil'

2.3,怀疑是rc.local加载的时候,python脚本中用到的psutil模块还没加载

手动执行脚start.sh能正常运行,说明start.sh和watchdog.py两个脚本本身没问题

3,方案一:让start.sh脚本后台运行,直到watchdog.py执行成功后才退出

3.1,start.sh脚本中最多重试5次后退出,间隔5秒

#!/bin/bash

LOG_FILE="/mnt/e/package/log/start.log"

LOG()
{
	TIMES=`date +"%Y-%m-%d %H:%M:%S.%3N"`
	echo "${TIMES} $1" >> $LOG_FILE
}

EXECUTE_CMD(){
	FILE_PATH=$1
	CMD=$2
	PROGRAM=$3
	RETRY=5  # 最多重试次数
	COUNT=1  # 当前重试次数
	while true; do
		cd $FILE_PATH	
		nohup $CMD $PROGRAM >> $LOG_FILE 2>&1 &  #  脚本重新启动 

		if [ $? -eq 0 ]; then
			# 执行成功,退出循环
			break
		fi

		if [ $COUNT -ge $RETRY ]; then
			# 达到最大重试次数,强制退出
			LOG "ERROR: Command['$CMD $PROGRAM'] failed even after $COUNT retries! Exiting."
			return 1
		fi

		COUNT=$(expr $COUNT + 1)
		LOG "Command['$CMD $PROGRAM'] failed, retrying in $INTERVAL seconds... (retry $COUNT/$RETRY)"
		sleep 5
	done

	LOG "Command['$CMD $PROGRAM'] succeeded after $COUNT retryies."
	return 0
}

EXECUTE_CMD /mnt/e/package python3 watchdog.py
LOG "EXECUTE_CMD /mnt/e/package python3 watchdog.py. result:$?"

exit $?

3.2,但开机启动后,发现返回了脚本执行成功,然后才打印了watchdog.py中报错

2023-04-22 02:20:56.955 Command['python3 watchdog.py'] succeeded after 1 retryies.
2023-04-22 02:20:56.958 EXECUTE_CMD /mnt/e/project/anweimian/package python3 watchdog.py. result:0
Traceback (most recent call last):
  File "/mnt/e/project/anweimian/package/watchdog.py", line 3, in <module>
    import psutil
ModuleNotFoundError: No module named 'psutil'

3.3,那么是不是会是nohup使start.sh脚本忽略了watchdog.py启动时的异常呢

nohup : 运行命令忽略挂起信号
& 是指后台运行;
nohup 的功能和& 之间的功能并不相同。其中,nohup 可以使得命令永远运行下去和用户终端没有关系。当我们断开ssh 连接的时候不会影响他的运行。而& 表示后台运行。当ssh 断开连接的时候(用户退出或挂起的时候),命令也自动退出。

#$CMD $PROGRAM >> $LOG_FILE 2>&1 &  #  脚本重新启动 
#修改为:
nohup $CMD $PROGRAM >> $LOG_FILE 2>&1 &  #  脚本重新启动 

3.4,去除nohup后,报错依旧,仍然不成功

2023-04-22 02:31:56.906 Command['python3 watchdog.py'] succeeded after 1 retryies.
2023-04-22 02:31:56.909 EXECUTE_CMD /mnt/e/project/anweimian/package python3 watchdog.py. result:0
Traceback (most recent call last):
  File "/mnt/e/project/anweimian/package/watchdog.py", line 3, in <module>
    import psutil
ModuleNotFoundError: No module named 'psutil'

4,方案二:不使用返回值而采用判断进程是否存

4.1,start.sh脚本如下所示

#!/bin/bash

LOG_FILE="/mnt/e/package/log/start.log"

LOG()
{
	TIMES=`date +"%Y-%m-%d %H:%M:%S.%3N"`
	echo "${TIMES} $1" >> $LOG_FILE
}

RUN_PYTHON()
{
	FILE_PATH=$1
	PROGRAM=$2
	while true  # 循环检测脚本是否停止
	do
		procnum=$(ps -ef | grep "$PROGRAM" | grep -v grep | wc -l) # 记录正在运行run.py的数量

		if [[ ${procnum} == 0 ]] ; then  # 如果run.py正在运行数量等于0,脚本中断,需要重启
			LOG "procnum[$procnum] not found $PROGRAM"
			cd $FILE_PATH
			nohup python3 $PROGRAM >> $LOG_FILE 2>&1 &  #  脚本重新启动 
			sleep 2  # 睡眠60s,每60s检测一次
		else
			LOG "procnum[$procnum] found $PROGRAM"
			sleep 60  # 睡眠60s,每60s检测一次
		fi
	
	done
}

RUN_PYTHON /mnt/e/package watchdog.py
LOG "RUN_PYTHON /mnt/e/package watchdog.py. result:$?"

exit $?

4.1,开机启动后,返现仍然无法启动watchdog.py,仍然报错psutil找不到

2023-04-22 02:42:47.519 procnum[0] not found watchdog.py
Traceback (most recent call last):
  File "/mnt/e/project/anweimian/package/watchdog.py", line 3, in <module>
    import psutil
ModuleNotFoundError: No module named 'psutil'

这就十分不应该,即便psutil加载慢,但总应该可以加载上的,但是不管start.sh脚本循环等待多久,watchdog.py脚本中一直报错

4.2,发现rc.local启动后的start.sh脚本进程属于root用户

在这里插入图片描述

4.3,而手动启动后的start.sh脚本进程属于username用户

2023-04-22 02:51:11.555 procnum[0] not found watchdog.py
2023-04-22 02:51:13.573 procnum[1] found watchdog.py
2023-04-22 02:52:13.590 procnum[1] found watchdog.py

在这里插入图片描述

4.4,那么有没有可能就是由于启动start.sh脚本的用户不同,一个有psutil模块,一个没有导致的失败呢?

脚本中增加如下命令
LOG "user name = ${USER}"

4.4.1,开机后rc.local脚本启动start.sh脚本,打印用户名是root

2023-04-20 00:55:24.271 user name = root

4.4.2,手动启动start.sh脚本,打印用户名是当前username

2023-04-20 00:56:44.329 user name = username

4.4.3,如果想要跟踪脚本运行的命令对不对,可以使用exec 1>>file和set -x

# 将输出到终端的打印都写入文件
exec 1>> $LOG_FILE 2>&1

#该命令后执行的命令都打印到终端
set -x

#取消执行的命令打印到终端
set +x

5,方案三:指定启动watchdog.sh的用户

5.1,修改start.sh脚本如下所示

#!/bin/bash

LOG_FILE="/mnt/e/package/log/start.log"

exec 1> $LOG_FILE 2>&1

LOG()
{
	TIMES=`date +"%Y-%m-%d %H:%M:%S.%3N"`
	echo "${TIMES} $1" >> $LOG_FILE
}

RUN_PYTHON()
{
	FILE_PATH=$1
	PROGRAM=$2
	set -x
	cd $FILE_PATH
	nohup echo password|sudo -S -u username python3 $PROGRAM >> $LOG_FILE 2>&1 &  #  脚本启动 
	set +x
}

RUN_PYTHON /mnt/e/package watchdog.py
LOG "RUN_PYTHON /mnt/e/package watchdog.py. result:$?"

exit $?

5.2,重启电脑后发现完美解决了

start.log日志打印如下所示

+ cd /mnt/e/package
+ nohup echo 931108
+ set +x
+ sudo -S -u wangxinyuan python3 watchdog.py
2023-04-22 03:20:51.157 RUN_PYTHON /mnt/e/package watchdog.py. result:0

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/447870.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SAP S/4HANA不是ERP了?

今天浏览了一下SAP官方帮助&#xff08;Help&#xff09;网站&#xff0c;有一个意外的发现&#xff0c;如上图&#xff1a;SAP S/4HANA和SAP ERP是分别显示的&#xff0c;这让我想起了前段时间一个朋友和我说&#xff1a;“S/4HANA现在都不叫ERP了&#xff0c;因为里面包括了超…

【C++初阶】C++入门(一):命名空间C++的输入输出缺省参数函数重载

​ ​&#x1f4dd;个人主页&#xff1a;Sherry的成长之路 &#x1f3e0;学习社区&#xff1a;Sherry的成长之路&#xff08;个人社区&#xff09; &#x1f4d6;专栏链接&#xff1a;数据结构 &#x1f3af;长路漫漫浩浩&#xff0c;万事皆有期待 文章目录 1.什么是C1.1 C的发…

最新Tuxera NTFS2023最新版Mac读写NTFS磁盘工具 更新详情介绍

Tuxera NTFS for Mac是一款Mac系统NTFS磁盘读写软件。在系统默认状态下&#xff0c;MacOSX只能实现对NTFS的读取功能&#xff0c;Tuxera NTFS可以帮助MacOS 系统的电脑顺利实现对NTFS分区的读/写功能。Tuxera NTFS 2023完美兼容最新版本的MacOS 11 Big Sur&#xff0c;在M1芯片…

Python统计学:如何理解样本统计量?

本期介绍样本统计量是怎么算的&#xff0c;并用Python来模拟随机抽样。用一个在鱼塘捞鱼的简单例子来理解样本均值的概念。 如何理解重复试验&#xff1f; 指能够在完全相同条件下进行多次的试验&#xff1b; 比如我们抛10枚硬币&#xff0c;用来计算正面出现的概率&#xff…

4.7 贝塞尔曲线

学习目标&#xff1a; 学习贝塞尔曲线可以遵循以下步骤&#xff1a; 1.了解基本概念和定义&#xff1a;学习贝塞尔曲线前需要了解贝塞尔曲线的基本概念和定义&#xff0c;如何定义一条贝塞尔曲线、控制点的概念以及贝塞尔曲线的几何性质等。 2.学习贝塞尔曲线的构造方法&…

Django搭建一个简易GPT网站

文章目录 环境安装创建主项目和应用程序在 settings.py 文件中注册应用程序在 views.py 文件中为应用程序创建视图配置应用程序的 URL创建和渲染模板KEY实现发送提示功能注意事项完整源码 环境安装 pip install django openai创建主项目和应用程序 处理完项目的环境后&#x…

第二个机器学习应用:乳腺癌数据集在决策树模型上的挖掘

目录 决策树优化与可视化 1 决策树分类 2 决策树可视化 3 显示树的特征重要性 特征重要性可视化 决策树回归 1 决策树回归 决策树优化与可视化 1 决策树分类 from sklearn.datasets import load_breast_cancer from sklearn.tree import DecisionTreeClassifier from sk…

基于C++开发的医院医学影像PACS 可二次开发,三维重建

医学影像PACS系统源码&#xff0c;集成三维影像后处理功能&#xff0c;包括三维多平面重建、三维容积重建、三维表面重建、三维虚拟内窥镜、最大/小密度投影、心脏动脉钙化分析等功能。系统功能强大&#xff0c;代码完整。有演示。 本套PACS系统专门针对医院工作流程设计的&am…

分布式ID生成策略总结

1、UUID 2、数据库自增ID 2.1、主键表 2.2、ID自增步长设置 3、号段模式 4、Redis INCR 5、雪花算法 6、美团(Leaf) 7、百度(Uidgenerator) 8、滴滴(TinyID) 总结比较 背景 在复杂的分布式系统中&#xff0c;往往需要对大量的数据进行唯一标识&#xff0c;比如在对…

springboot中的日志

作者&#xff1a;~小明学编程 文章专栏&#xff1a;spring框架 格言&#xff1a;热爱编程的&#xff0c;终将被编程所厚爱。 目录 为什么需要日志 如何使用日志功能 日志的打印 获取日志对象 使用日志对象打印日志 日志级别 为什么我们需要把日志分为如此多的种类呢&am…

今天面试招了个25K的测试员,从腾讯出来的果然都有两把刷子···

公司前段时间缺人&#xff0c;也面了不少测试&#xff0c;前面一开始瞄准的就是中级的水准&#xff0c;也没指望来大牛&#xff0c;提供的薪资在15-25k&#xff0c;面试的人很多&#xff0c;但平均水平很让人失望。看简历很多都是4年工作经验&#xff0c;但面试中&#xff0c;不…

《系统架构设计》-07-面向领域的技术设计

文章目录 1 实体与值对象1.1 实体对象1.1.1 唯一标识&#xff08;Identity&#xff09;1.1.2 可变性贫血模型充血模型 1.2 值对象1.3 示例&#xff08;识别实体和值对象&#xff09;1&#xff09;识别实体对象2&#xff09;提取值对象3&#xff09;挖掘实体的关键行为4&#xf…

solidworks2022 - feature works 变灰的解决方法

文章目录 solidworks2022 - feature works 变灰的解决方法概述实验feature works 变灰问题的重现备注END solidworks2022 - feature works 变灰的解决方法 概述 feature works 用于step文件转零件. 一般是不同版本的solidworks交换文件的方法. 今天突然发现, 我自己转出的ste…

Spring框架使用总结

Spring框架使用 前言处理事务管理声明式事务&#xff1a;编程式事务&#xff1a; 框架核心常见注解 AOP&#xff08; 面向切面编程&#xff09;切面和通知有哪些类型&#xff1f;切面的类型通知类型AOP实现使用场景 IOC(管理所有的JavaBean)依赖注入&#xff08;DI&#xff09;…

像素比特行列置乱加密算法安全性分析

比特行列置乱加密 将MN大小的灰度图像每个像素值转换为8bit二进制&#xff0c;得到M8N大小的二值图像。 基于加密秘钥&#xff0c;生成随机序列TM和TN分别对二进制图像的行列进行置乱&#xff0c;生成置乱加密后的图像。 Logistic混沌序列加密&#xff1a; 选择明文攻击过程 …

Node内置模块 【path模块】

文章目录 &#x1f31f;前言&#x1f31f;path模块&#x1f31f;引用模块&#x1f31f;常用属性&#x1f31f;path.sep&#x1f31f;在MacOSX、 Unix、Linux操作系统上&#xff1a;&#x1f31f;在 Windows 上&#xff1a; &#x1f31f;常用方法&#x1f31f;将路径转换为对象…

【python视图1】networkx操作Graph图

一、说明 数据可视化需要显示种种数据&#xff0c;matplotlib负责曲线类画图&#xff0c;然而类似于图论的操作用什么方法。这里用networkx程序包完成。本文专门介绍这种程序包的用法。 二、生成图&#xff08;Creating a graph&#xff09; 2.1 创建一个没有节点和边的空图。…

Linux:centos 7:查看运行级别 控制init运行级别 已安装图形化以后设置开机进入图形化或命令行

0 target 关机状态&#xff0c;使用该级别时将关闭主机 1 rescue.target 单用户模式&#xff0c;不需要密码验证即可登录系统&#xff0c;多用于系统维护 …

HTTP 的工作原理

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、简单 HTTP二、HTTP 连接请求 I请求Ⅱ 持久 HTTP并执行 HTTP默认浏览器连接设置总结 前言 在处理 Web 性能监控或优化时&#xff0c;了解 HTTP 协议的基础知…

leetcode每日一题——美团笔试题【3】

第一题&#xff1a; 股票的最大利润 假设把某股票的价格按照时间先后顺序存储在数组中&#xff0c;请问买卖该股票一次可能获得的最大利润是多少&#xff1f;示例 1:输入: [7,1,5,3,6,4] 输出: 5 解释: 在第 2 天&#xff08;股票价格 1&#xff09;的时候买入&#xff0c;在…