当前位置: 首页 > news >正文

Ubuntu 开机自启动 .py / .sh 脚本,可通过脚本启动 roslaunch/roscore等

前言

        项目中要求上电自启动定位程序,所以摸索了一种 Ubuntu 系统下开机自启动的方法,开机自启动 .sh 脚本,加载 ROS 环境的同时启动 .py 脚本。在 . py 脚本中启动一系列 ROS 节点。

一、 .sh 脚本的编写

#!/bin/bash
# gnome-terminal -- bash -c "/home/wu/startup.sh; exec bash"
sleep 2echo "----------加载 ROS 环境----------"
source /opt/ros/noetic/setup.bash 
sleep 2
echo $ROS_PACKAGE_PATHecho "----------启动 python 脚本----------"
/usr/bin/python3 /home/wu/test.py# sh脚本等待所有后台进程完成后结束
wait
exit 0

        启动 .sh 脚本时,首先沉睡 2 秒,等待其它部分启动完成后加载 ROS 环境,之后输出 $ROS_PACKAGE_PATH 确定 ROS 环境是否加载好,最后启动 .py 脚本。

二、 .py 脚本的编写

        首先安装依赖 wmctrl。wmctrl 是一个用于控制 X Window 管理器的命令行工具,通常用于 Linux 系统,特别是对窗口进行操作和管理。

sudo apt-get update
sudo apt-get install wmctrl
#!/usr/bin/python3.8
# coding=utf8
import subprocess
import rospyi = 101def close_terminal_by_name(terminal_name):# 使用 wmctrl -l 来列出所有窗口和其标题wmctrl_process = subprocess.Popen(["wmctrl", "-l"], stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)stdout, _ = wmctrl_process.communicate()# 在输出中查找指定名称的终端for line in stdout.splitlines():if terminal_name in line:# 获取终端的窗口 ID,并使用 wmctrl -i -c 命令关闭该终端window_id = line.split()[0]subprocess.run(["wmctrl", "-i", "-c", window_id])print("已关闭终端:", terminal_name)return# 如果未找到指定名称的终端print("未找到名称为", terminal_name, "的终端")def step(commands):command_str = " && ".join(commands)  # 将命令列表连接为一个字符串,使用 && 分隔# print(command_str)# 使用 exec bash 保持终端窗口打开command_str = command_str + "; exec bash"# subprocess.run() 函数用于执行外部命令。它会创建一个新的子进程,并等待子进程执行完成后返回。# gnome-terminal" 是要执行的命令,即打开一个新的终端# "--" 表示后面的参数将被传递给 gnome-terminal 命令# 使用 bash -c 执行命令rospy.sleep(1)subprocess.run(["gnome-terminal", "--", "bash", "-c", command_str]) # title 无效???# 添加标题:"--title", str(i),def step_name(commands):global icommand_str = " && ".join(commands)  # 将命令列表连接为一个字符串,使用 && 分隔# print(command_str)# 使用 exec bash 保持终端窗口打开command_str = command_str + "; exec bash"# subprocess.run() 函数用于执行外部命令。它会创建一个新的子进程,并等待子进程执行完成后返回。# gnome-terminal" 是要执行的命令,即打开一个新的终端# "--" 表示后面的参数将被传递给 gnome-terminal 命令# 使用 bash -c 执行命令rospy.sleep(1)subprocess.run(["gnome-terminal", "--title", str(i), "--", "bash", "-c", command_str]) # title 无效???# 添加标题:"--title", str(i),i = i + 1def start_roscore():command = "roscore"print("---启动{}".format(command))subprocess.Popen(["gnome-terminal", "--", "bash", "-c", command])def kill_roscore():close_terminal_by_name("roscore http://WP:11311/")if __name__ == '__main__':start_roscore() # 第一时间启动roscorerospy.sleep(2)rospy.init_node('test')rospy.loginfo('*****************************')command_str = ["cd /","sudo apt-get update"]rospy.sleep(1)step(command_str)rospy.sleep(1)

        .py 脚本主要包括 3 个函数, step(commands), step_name(commands) 和 close_terminal_by_name(terminal_name)

  • step(commands):将要输入到终端的命令以如下方式定义
    # 雷达驱动command_drive = ["cd /home/wu/3rdparty/driver/ws_livox","source ./devel/setup.bash","roslaunch livox_ros_driver2 msg_MID360.launch"]

        然后将 command_drive 以参数形式传入 step(commands) 函数中,启动 rosrun 节点。

        当以这种方式启动 rosrun 节点时,wmctrl 中没有相应标题,无法通过 title 关闭该节点。

        当以这种方式启动 roslaunch 节点时,wmctrl 中有相应标题,可通过 title 关闭该节点,默认 title 如下:

/home/wu/3rdparty/driver/ws_livox/src/livox_ros_driver2/launch_ROS1/msg_MID360.launch http://localhost:11311

        前半部分为 .roslaunch 文件路径,后半部分 http://localhost:11311 是 ROS 中的 ROS Master 运行的地址。

  • step_name(commands)

        通过 step_name(commands) 函数启动 rosrun 节点时,可以为其定义 title,定义的 title 为字符串 101。当启动多个step_name(commands) 函数时,title 以 101 为起点递增。此时,可将 101 作为参数传入 close_terminal_by_name(terminal_name) 函数中关闭 ros 节点。

  • close_terminal_by_name(terminal_name)

        将 wmctrl 的 title 作为参数传入该函数,关闭相应的 ros 节点。

三、sudo 无需输入密码

        当 command 中包含 sudo 命令时,需要手动输入密码,会影响脚本的自动化,故通过修改 ubuntu 设置 sudo 时无需输入密码。

        使用 visudo 命令编辑 sudoers 文件:

sudo visudo

        在最后一行添加如下命令,然后 ctrl + X 离开。

UserName ALL=(ALL) NOPASSWD: ALL

        设置成功后输入 sudo 命令将不会要求输入密码。

四、Ubuntu 启动应用程序 设置开机自启动 .sh 脚本

        完成上述设置后,按照如下配置

 

 

        输入以下命令开机自启动 .sh 脚本 

gnome-terminal -- bash -c "/home/wu/startup.sh; exec bash"

参考

        gnome-terminal - A terminal emulator for GNOME

        Ubuntu 开机自启动python程序或roslaunch的方法

        ubuntu中的sudoers文件损坏,修复办法(附图、详细)

        普通用户执行 sudo 命令而不用输入密码

相关文章:

  • DMDSC更换DCR和VOTE磁盘
  • MySQL-数据库设计
  • tomcat的安装,管理与配置
  • ECMAScript与Python、Java和C++比较的详细的代码案例
  • Excel中查找某个值的位置,用位置取值
  • 浅谈stm32的GPIO引脚配置模式
  • 在Ubuntu 16.04上安装Virtualmin与Webmin、LAMP、BIND和PostFix的方法
  • Swagger配置且添加小锁(asp.net)(笔记)
  • 遥感图像语义分割数据集制作(使用ArcGIS Pro)
  • 只申请一块sizeofimage的内存能否实现PE文件的拉伸
  • 【PyTorch】生成对抗网络
  • C++游戏开发详解:从入门到实践
  • c++primier第十二章类和动态内存
  • openKylin--安装 .net6.0
  • 锁住K8S集群版本和系统内核版本
  • 《深入 React 技术栈》
  • canvas绘制圆角头像
  • java第三方包学习之lombok
  • JAVA之继承和多态
  • Lsb图片隐写
  • October CMS - 快速入门 9 Images And Galleries
  • RxJS 实现摩斯密码(Morse) 【内附脑图】
  • Solarized Scheme
  • TCP拥塞控制
  • UEditor初始化失败(实例已存在,但视图未渲染出来,单页化)
  • vue从创建到完整的饿了么(18)购物车详细信息的展示与删除
  • windows下使用nginx调试简介
  • 安装python包到指定虚拟环境
  • 从0实现一个tiny react(三)生命周期
  • 前端 CSS : 5# 纯 CSS 实现24小时超市
  • 前端之React实战:创建跨平台的项目架构
  • 前端之Sass/Scss实战笔记
  • 用jquery写贪吃蛇
  • 阿里云IoT边缘计算助力企业零改造实现远程运维 ...
  • ​埃文科技受邀出席2024 “数据要素×”生态大会​
  • #if等命令的学习
  • #pragma data_seg 共享数据区(转)
  • $ git push -u origin master 推送到远程库出错
  • (c语言+数据结构链表)项目:贪吃蛇
  • (vue)el-tabs选中最后一项后更新数据后无法展开
  • (ZT)薛涌:谈贫说富
  • (第二周)效能测试
  • (附源码)springboot工单管理系统 毕业设计 964158
  • (七)Knockout 创建自定义绑定
  • (求助)用傲游上csdn博客时标签栏和网址栏一直显示袁萌 的头像
  • (四)Android布局类型(线性布局LinearLayout)
  • (四)c52学习之旅-流水LED灯
  • (四)鸿鹄云架构一服务注册中心
  • (一)pytest自动化测试框架之生成测试报告(mac系统)
  • (一)Spring Cloud 直击微服务作用、架构应用、hystrix降级
  • .gitignore文件---让git自动忽略指定文件
  • .NET Reactor简单使用教程
  • .net 受管制代码
  • .net6 webapi log4net完整配置使用流程
  • .net对接阿里云CSB服务