Ubuntu20.04 设置开机自启脚本、开机自启命令(ubuntu 自启,ubuntu 开机自启)rc(run command)(systemd)(/etc/rc.local)(开机启动原理)开机自启动

一定要注意 ubuntu 的版本,有的工具支持到某个版本就不支持了。。。

 

我们的 ubuntu 系统版本是 20.04,我们在这个版本的基础上查找开机自启的方法

Ubuntu 20.04 的服务管理是基于 systemd 的,因此设置服务自启动最推荐的方法是创建一个 systemd 服务文件,配置好要执行的服务
参考文章:Ubuntu 20.04 设置开机自启动

Linux/Ubuntu 开机启动原理

参考文章:Ubuntu 20.04 设置开机自启脚本

Linux 的开机启动顺序

要想整明白后面的开机启动的设置方法,最好不要只知其然而不知其所以然,这里要先从 Linux 的开机启动顺序开始说起。

下面介绍三种添加开机自启脚本的方法,所测试的系统为 Ubuntu 20.04

Linux 系统启动从你的设备接上电源按下开关开始到你登录系统结束,中间有一个复杂但很连贯的过程:

  1. 加载 BIOS(Basic Input Output System,基本输入输出系统)。获取 CPU 相关信息、设备启动顺序信息、硬盘信息、内存信息、时钟信息等信息
  2. 读取 MBR(Master Boot Record,主引导记录)。MBR 就是磁盘上第 0 磁道的第一个扇区,里面含有 boot loader 的代码。
  3. 运行 boot loader。Boot Loader 就是在操作系统内核运行之前运行的一段小程序。通过这段小程序,我们可以初始化硬件设备、建立内存空间的映射图,从而将系统的软硬件环境带到一个合适的状态,以便为最终调用操作系统内核做好一切准备。
  4. 加载内核。根据 boot loader 设定的内核映像所在的路径,读取内核映像并进行解压缩操作。
  5. 运行 init 程序。init 永远是系统启动后运行的的第一个进程,PID(进程编号)为 1。位置在 sbin/init ,之后会按照设置执行一大堆系统启动时要启动的脚本、加载的驱动等功能,我们要设置的开机启动项就是在这一步执行的。
  6. 执行 /bin/login 程序,进入登录状态。

init 系统能够管理和控制 init 进程的行为,并负责组织和运行许多独立的或相关的工作,让系统进入一个用户设定的运行模式中。大多数 Linux 发行版的 init 系统是 system V 相兼容的,因此被称为 sysvinit,sysvinit 主要依赖于 shell 脚本,但是他一次一个串行的启动进程,决定了它最大的弱点:启动太慢。如果是服务器这类极少进行系统开关操作的话还好,但是如果是个人电脑这样需要经常开关机的话,开机时间太长就难以忍受了。

为了能够更快地启动系统,开发者们对 sysvinit 进行了改进,先后出现了 upstart 和 systemd 这两个主要的新一代 init 系统。目前最新的 Ubuntu 系统就是采用的 systemd 来管理系统,不过仍然兼容 init 系统的启动模式。可以看到 Ubuntu20 的 /sbin/init 是软链接到 /lib/systemd/systemd 上的。systemd 与 init 虽然启动过程不太一样,但最终的目的是一致的,都是要启动那一堆需要开机运行的脚本文件。

在 init 系统模式下,内核调用 init 进程后会首先获取系统运行级别(run-level)的信息,运行级别在这里不是启动优先级,可以理解为运行模式,运行级别共有 0~6 七种:

  • 0:关机
  • 1:单用户模式
  • 2:多用户模式,没有网络支持
  • 3:多用户模式,有网络支持
  • 4:保留,未使用
  • 5:X11,与运行级别 3 类似,但加载使用 X-windows 支持的图形界面
  • 6:重启

这几种模式有什么用呢?举个例子,在 Ubuntu 的终端下,重启指令除了 reboot 外,使用 init 6 也可以实现重启,6 对应的运行级别就是重启,类似地,运行 init 0 指令对应的就是关机。

知道启动级别后就到 /etc/rc.d 文件夹中查找相应的脚本并运行。还会在 /etc/modules-load.d/modules.conf 文件中查找装载到内核的模块。

rc.d 中含有 rc.sysinit、rcN.d(N=0~6,即不同的运行级别对应的运行文件夹,根据运行级别的不同,系统会运行 rc0.d 到 rc6.d 中的相应的脚本程序,来完成相应的初始化工作和启动相应的服务)、rc.local 等文件及或脚本,目前 Ubuntu 已经没有 rc.d 文件夹了,而是把这个文件夹的大多内容直接放在了 /etc 文件夹下了,另外 rc.local 如果需要用到的话还需要自行创建。rc.local 是在所有 init 脚本执行完之后才会运行的脚本,也就是说留给用户用来做一些拓展功能的脚本。

打开 rcN.d 文件夹可以看到里面的文件都是以 S 或者 K 夹数字开头的脚本,S 待表 Start,K 代表 Kill ,运行脚本时系统会根据这俩前缀符号来确定传入 start 或者 stop 参数。后面的数字代表执行优先级,也就是运行或者停止的执行优先级。

Ubuntu 20.04 设置开机自启脚本

ubuntu16.04 以后的版本不再使用 initd 管理系统,因此不再支持 update-rc.d 方式添加开机自启脚本。

Ubuntu18 版本开始,使用了 systemd 替代了 initd 管理系统,并且默认已经取消了 /etc/rc.local 文件。只能使用 systemctrl 命令进行添加。

systemd 默认读取 /etc/systemd/system 下的配置文件,该目录下的文件会链接 (软链接)/lib/systemd/system/ 下的文件。一般系统安装完 /lib/systemd/system/ 下会有 rc-local.service 文件,即我们需要的配置文件。

下面介绍使用 rc-local.service 添加开机自启脚本的方法,所测试的系统为 Ubuntu 20.04

使用 rc-local.service

rc-local.service 是系统自带的一个开机自启服务,但是在 ubuntu 20.04 上,该服务默认没有开启。

1、修改 rc-local.service 文件

rc-local.service 文件 路径 /lib/systemd/system/rc-local.service

sudo vim /lib/systemd/system/rc-local.service

在文件的最后面添加 [Install] 段的内容,可以看出,/etc/rc.local 的启动顺序是在网络后面,但是显然它少了 Install 段,也就没有定义如何做到开机启动,所以显然这样配置是无效的。 因此我们就需要在后面帮他加上 [Install] 段:

[Unit]
Description=/etc/rc.local Compatibility
Documentation=man:systemd-rc-local-generator(8)
ConditionFileIsExecutable=/etc/rc.local
After=network.target
 
[Service]
Type=forking
ExecStart=/etc/rc.local start
TimeoutSec=0
RemainAfterExit=yes
GuessMainPID=no
 
#这一段原文件没有,需要自己添加
# arnold add 20221206
[Install]
WantedBy=multi-user.target
Alias=rc-local.service

20220105:Alias=rc-local.service 这一句有点奇怪,加了没加好像没有影响???(在 dalong 矿下测试)

rc-local.service 内容解释
[Unit]  # 区块:启动顺序与依赖关系
Description  # 服务的描述
Documentation
ConditionFileIsExecutable # 指定了执行的文件, 表示服务要启动的程序(或脚本)
After=network.target  # 表示该服务的依赖关系,表示在 network.target 这个 target 后面进行执行。也就是网络启动完成之后,执行 /etc/rc.local 文件。

[Service] # 区块:启动行为,如何启动,启动类型。
Type=forking # 后台运行的形式
ExecStart=/etc/rc.local start  # 启动服务的命令(命令必须写绝对路径)
TimeoutSec=0
RemainAfterExit=yes
GuessMainPID=no

#这一段原文件没有,需要自己添加
[Install]  # 区块,定义如何安装这个配置文件,即怎样做到开机启动
WantedBy=multi-user.target # multi-user.target 表示多用户命令行状态
Alias=rc-local.service # 指的是表示该服务所属 target

上述命令只写了启动的,重启、停止等可以根据自己情况添加。
注意:启动、重启、停止命令全部要求使用绝对路径
ExecReload 为服务的重启命令
ExecStop 为服务的停止命令
PrivateTmp=True 表示给服务分配独立的临时空间

2. 创建 /etc/rc.local

Ubuntu 20.04 默认不存在 /etc/rc.local,需要自己创建 vi /etc/rc.local

在该文件中添加脚本内容,即开机脚本需要实现的功能,这里只是简单地实现了向某一个文件里填充数据功能。

#!/bin/bash

# 将你需要执行的命令写在这里,禁止写入死循环命令
#echo "开机启动测试_$(who)_$(date +%Y.%m.%d_%H.%M.%S)" >> /home/test.log
who > /home/ky_test_user.log 2>&1 &	# 这个打印不出来。。。。不知道怎么回事,但貌似拥有root权限??
/kyai_nv/kyai_nv_server.sh >> /kyai_nv/ky_sh.log 2>&1 &
# 这个可以正常启动没问题的,而且ps进程发现是root用户启动的

exit 0

在这里插入图片描述

20230113 更新下自启脚本

CHpython 输出日志太多了,而且直接输出到 ky_sh.log 里了,这里不给他输出了

#!/bin/bash

# 将你需要执行的命令写在这里,禁止写入死循环命令

# 启动慧源旷脑ngrest kyai服务
# /kyai_nv/kyai_nv_server.sh >> /kyai_nv/ky_sh.log 2>&1 &
/kyai_nv/kyai_nv_server.sh > /dev/null 2>&1 &

# 这个可以正常启动没问题的,而且ps进程发现是root用户启动的

exit 0

3. 修改 /etc/rc.local 权限

脚本要想运行,还需要设置脚本的可执行权限,使用 sudo chmod 777 /etc/rc.local 或 sudo chmod +x /etc/rc.local 修改该文件的权限。

4. 启动 rc-local.service

systemd 默认读取 /etc/systemd/system 下的配置文件,所以还需要在 /etc/systemd/system 目录下创建软链接

输入以下命名,使能 rc-local 服务。

sudo systemctl enable rc-local.service 
# 或者
sudo systemctl enable rc-local

# 以上两个命令其实是一个软链接命令

ln -s /lib/systemd/system/rc-local.service /etc/systemd/system/rc-local.service
实际上就是在 /etc/systemd/system/ 目录下创建了一个软链接。

即 /lib/systemd/system/rc-local.service 链接到 /etc/systemd/system/rc-local.service
系统在开机后会自动去 /etc/systemd/system/ 目录下读取需要启动的服务配置

5. 检查服务状态

使用 sudo systemctl status rc-local.service 查看 rc-local 服务的状态, 显示 loaded 和 enabled。

root@nvidia-desktop:/kyai_nv# systemctl status rc-local.service
● rc-local.service - /etc/rc.local Compatibility
     Loaded: loaded (/lib/systemd/system/rc-local.service; enabled; vendor preset: enabled)
    Drop-In: /usr/lib/systemd/system/rc-local.service.d
             └─debian.conf
     Active: inactive (dead)
       Docs: man:systemd-rc-local-generator(8)
root@nvidia-desktop:/kyai_nv# 

6. 重启验证

重启没什么问题,貌似会以 root 权限去运行那个脚本

参考文章 1:Ubuntu 设置开机自动启动脚本 / 程序的各种方法

参考文章 2:Ubuntu 20.04 设置开机自启脚本

参考文章 3:Ubuntu 20.04 设置开机自启脚本

 

前言

         本文针对的是 Ububtu 20.04 系统的设置操作。

         用过 CentOS 系统的朋友应该知道,如果你想添加开机自启命令的话,可以在 rc.local 中设置,但在 Ubuntu 20.04 设置完后没有成功,这是什么原因?这是因为从 Ubuntu16 以后,开始取消这一项的设置,并把这个设置的权限交给了 systemd 来处理,但很多朋友发现 systemd 非常不好用,那我们要怎么操作来完成开机自启命令的添加呢?

        其实 Ubuntu 20.04 取消了 rc.local 的设置,但并没有真正的删除这项的配置,我们可以自己恢复 rc.local 来重新设置开机自启命令。

设置步骤

第一步 检查系统中 rc-local.service

        执行 ls /lib/systemd/system 你可以看到有很多启动脚本,其中就有我们需要的 rc-local.service

第二步 修改 rc-local.service

        打开 rc-local.service 脚本内容,内容如下:

一般正常的启动文件主要分成三部分

  • [Unit] 段:启动顺序与依赖关系
  • [Service] 段:启动行为,如何启动,启动类型
  • [Install] 段:定义如何安装这个配置文件,即怎样做到开机启动

可以看出,/etc/rc.local 的启动顺序是在网络后面,但是显然它少了 Install 段,也就没有定义如何做到开机启动,所以显然这样配置是无效的。 因此我们就需要在后面帮他加上 [Install] 段:

[Install]
WantedBy=multi-user.target  
Alias=rc-local.service

PS:添加了 [Install] 内容后,下面两行的 WantedBy 和 Alias 两个英文跟上面的都是绿色的,要是绿色才有用。

一般需要先修改 rc-local.service 的权限才可以进行编辑。

sudo chmod 777 /lib/systemd/system/rc-local.service

 第三步 新建并修改 rc.local 文件

        查看系统中有无 /etc/rc.local 这个文件,没有则自己创建一个。

        然后把你需要启动脚本写入 /etc/rc.local ,我们不妨写一些测试的脚本放在里面,以便验证脚本是否生效.

sudo vim /etc/rc.local

#!/bin/sh

exit 0

 PS:#!/bin/sh 这一行一定要加上!一定要加上!

 第四步 权限修改

        给 rc.local 加上权限

sudo chmod +x /etc/rc.local

第五步 建立软连接

 ln -s /lib/systemd/system/rc.local.service /etc/systemd/system/ 

第六步 添加要开机自启的命令

 sudo vim /etc/rc.local


在 exit 0 前加入自己的命令即可

扩展

        如果在 /etc/rc.local 中添加的是 ./test.sh 这种类型的,要在末尾加上 &,不然重启 ubuntu 的时候会卡在启动界面进不去系统。

 

在较新的 Ubuntu 版本(如 Ubuntu 18.04)中,使用 systemd 替代了旧的 /etc/init.d 系统启动脚本。然而,如果你需要使用旧的 /etc/init.d 方式来设置自启动服务,可以按照以下步骤进行操作:

  1. 创建启动脚本:使用文本编辑器创建一个启动脚本文件,以 .sh 结尾,并将其放置在 /etc/init.d 目录中。例如,创建名为 my-service.sh 的脚本:

    sudo nano /etc/init.d/my-service.sh
  2. 在脚本中添加启动逻辑:在脚本中添加启动和停止服务的逻辑。以下是示例启动脚本的基本结构:

    #!/bin/bash
    ### BEGIN INIT INFO
    # Provides:          my-service
    # Required-Start:    $remote_fs $syslog
    # Required-Stop:     $remote_fs $syslog
    # Default-Start:     2 3 4 5
    # Default-Stop:      0 1 6
    # Short-Description: My Service
    # Description:       Enable service provided by My Service.
    ### END INIT INFO
    
    # Add your start and stop commands here
    
    case "$1" in
      start)
        # Start the service
        ;;
      stop)
        # Stop the service
        ;;
      restart)
        # Restart the service
        ;;
      *)
        echo "Usage: $0 {start|stop|restart}"
        exit 1
        ;;
    esac
    
    exit 0
     
     

    在 start 部分添加启动服务的命令,在 stop 部分添加停止服务的命令,以及在 restart 部分添加重新启动服务的命令。

  3. 设置脚本的执行权限:运行以下命令设置脚本的执行权限:

    sudo chmod +x /etc/init.d/my-service.sh
  4. 启用自启动服务:运行以下命令以将脚本添加到启动项列表中:

    sudo update-rc.d my-service.sh defaults
  5. 启动服务:运行以下命令以启动服务:

    sudo service my-service start

    将 my-service 替换为你在第 1 步中创建的脚本的名称。

现在,你的服务将在系统开机时自动启动,并且可以使用 service 命令来控制服务的启动、停止和重新启动。

请注意,虽然仍然可以使用 /etc/init.d 方式来设置自启动服务,但 systemd 已成为 Ubuntu 默认的服务管理工具,并提供更强大和灵活的功能。因此,建议尽可能使用 systemd 来管理自启动服务。

 

posted @ 2024-07-01 11:08  CharyGao  阅读(2083)  评论(1编辑  收藏  举报