Linux 下设置开机自启动的方法

笔者的运行环境:

  • 设置成功过的 Linux:

    • RedHat Enterprise Linux 9 x86_64

    • CentOS 8 x86_64

事先准备

  1. 进行这个教程之前,必须要先安装好一个 Linux 操作系统。这个 Linux 操作系统可以安装在虚拟机中,也可以安装在真实的电脑中。关于这方面的内容,可见笔者的其它博客:

    各种操作系统安装教程大全:
    https://blog.csdn.net/wangpaiblog/article/details/115436520

    为了方便远程输入命令、将文件加入到 Linux 操作系统中,最好还要在一台 Windows 操作系统上面使用一种终端控制软件,如 Xshell、Xftp 等。关于这方面的内容,可见笔者的另一篇博客:

    如何在 Windows 主机上访问本地局域网中的 Linux 主机:
    https://blog.csdn.net/wangpaiblog/article/details/120052152

  2. 本文主要针对一些离线免安装的应用。很多应用在安装会自动设置开机启动,对这种应用不需要设置开机启动。联网应用在启动后会占用端口号,如果想验证这种应用有没有启动,可以使用如下命令。

    netstat -na | grep 该应用的端口号

    如果输出了该应用的端口号被使用的信息,说明该应用已经启动。

对于普通的 Linux

  1. 这种方法适用于一些有 Linux 的启动目录 init.d 的 Linux。对本方法而言,读者需要先提供一种供开机启动的脚本,不妨设为 myapp


    【踩坑提醒】

      此脚本中不能使用 Linux 的环境变量。Linux 的环境变量一般在文件 /etc/profile 中设置,而文件 /etc/profile 是在每一个用户登录 Shell 时才会读取的。在 Linux 启动之时此文件中的环境变量不会起作用。因此,如果需要使用 Linux 的环境变量,请将环境变量直接定义在此脚本开头。


  2. 将此脚本移动或复制到 Linux 的启动目录 init.d 中,然后对其添加执行权限。

    chmod +x /etc/rc.d/init.d/myapp

  3. 设置 myapp 开机自启动。

    chkconfig myapp on

  4. 输入以下命令验证是否成功设置了 myapp 开机自启动:

    chkconfig --list

    如果输出结果含 myapp,且 3、4、5 值均为 ,说明设置成功。输出如下所示:

    myapp 0:关 1:关 2:开 3:开 4:开 5:开 6:关

  5. 重启电脑试一下是否真正成功。输入以下命令重启电脑:

    reboot

    重启后,马上输入以下命令:

    netstat -na | grep 该应用的端口号

    如果输出了端口号被使用的信息,说明 myapp 开机自启动成功。

对于 RedHat Enterprise Linux 9

  1. 对于一些较新的 Linux,它没有提供上面的启动目录 init.d,而是改为使用服务来启动,这样设计要规范一些。对于使用服务来启动,需要编写一个 .service 文件放置在目录 /etc/systemd/system 下,并使用 systemctl 命令来控制这个服务。

    对本方法而言,读者需要先提供一些关于应用启动、停止等命令。

  2. 使用如下命令在目录 /etc/systemd/system 下创建一个关于 myapp 的 .service 文件。

    touch /etc/systemd/system/myapp.service

  3. 编辑该文件,在其中写入如下内容。

    [Unit]
    Description=myapp-server
    After=network.target
    
    [Service]
    ExecStart=应用启动命令
    ExecReload=应用重新加载命令
    ExecStop=应用停止命令
    PrivateTmp=true
    Type=forking
    
    [Install]
    WantedBy=multi-user.target
    

    【说明】

    1. 对于 [Unit]

      • Description:描述该服务的文字说明。

      • Documentation:关于该服务的相关文档的URL。

      • Requires:指定该服务所依赖的其他服务,如果这些服务没有运行,那么该服务也不会启动。

      • Wants:指定该服务所希望依赖的其他服务,但不会影响该服务的启动。

      • After:指定该服务应在哪些其他服务启动之后再启动。

      • Before:指定该服务应在哪些其他服务启动之前启动。

      • Conflicts:指定该服务与哪些其他服务冲突,如果这些服务之一正在运行,那么该服务将不会启动。

      • BindsTo:指定该服务与哪些其他服务绑定,如果这些服务之一停止运行,那么该服务也会停止。

      • PartOf:指定该服务是哪个服务的一部分,如果该服务停止运行,那么整个服务也会停止。

    2. 对于 [Service]

      • 上面的部分以 Exec 开头属性代表着某个命令 systemctl 命令关键字 myapp。对应关系如下:

        • ExecStart:启动服务的命令,对应 systemctl start myapp

        • ExecStop:停止服务的命令,对应 systemctl stop myapp

        • ExecReload:重新加载服务的命令,对应 systemctl reload myapp

          重新加载服务并不是重启服务。重新加载通常用于重新加载服务的配置文件或重新加载某些资源,以便服务可以在不中断运行的情况下应用更改。

      • 也有一些以 Exec 开头的属性需要提供相应的脚本,但它们没有对应的命令 systemctl 命令关键字 myapp

        • ExecStartPre:在启动服务之前执行的命令。

        • ExecStartPost:在启动服务之后执行的命令。

        • ExecStopPre:在停止服务之前执行的命令。

        • ExecStopPost:在停止服务之后执行的命令。

      • 其它属性:

        • Type:指定服务的类型,可以是simpleforkingoneshotdbusnotify等。

        • WorkingDirectory:指定服务的工作目录。

        • User:指定服务运行的用户。

        • Group:指定服务运行的用户组。

        • Restart:指定服务在退出后是否自动重启,可以是noon-successon-failureon-abnormalon-abortalways等。

        • RestartSec:指定服务重启之间的延迟时间。

        • Environment:指定服务的环境变量。

        • ExecStartPre:指定在服务启动之前要执行的命令或脚本。

        • ExecStartPost:指定在服务启动之后要执行的命令或脚本。

        • ExecStopPre:指定在服务停止之前要执行的命令或脚本。

        • ExecStopPost:指定在服务停止之后要执行的命令或脚本。

    3. 对于 [Install]

      • WantedBy: 指定服务所属的目标(target),即服务应该在哪个目标中启动。可以指定为一个或多个目标,多个目标之间用空格分隔。例如,WantedBy=multi-user.target表示服务应该在multi-user.target目标中启动。

      • RequiredBy: 指定服务所需的目标(target),即服务应该在哪个目标中必须启动。与WantedBy类似,可以指定为一个或多个目标,多个目标之间用空格分隔。

      • Also: 指定其他服务的安装选项。可以指定为一个或多个服务名称,多个服务之间用空格分隔。例如,Also=other.service表示在安装当前服务时,也同时安装other.service

    4. 补充:

      • 有些命令没有对应的属性,如 systemctl restart myapp。该重启命令相当于停止和启动命令的组合(如果服务如果未启动会直接执行启动命令,如果已启动会先执行停止再启动)。

    【注意】

    1. 上面的命令必需使用该命令的全路径。不能因为前面在文件 /etc/profile 设置了 myapp 的环境变量,此处命令就不使用全路径了。文件 /etc/profile 是在每一个用户登录 Shell 时才会读取的。在 Linux 启动之时此文件中的环境变量不会起作用。

      如果想在 Linux 启动时使用环境变量,可以将此环境变量单独放入一个文件(不妨设为 /etc/systemd/system/myappenv.conf)中,然后在本 .service 文件 /etc/systemd/system/myapp.service 中的 [Service] 部分使用 EnvironmentFile 属性导入这个环境变量配置文件。

      [Service]
      EnvironmentFile=/etc/systemd/system/myappenv.conf
      
    2. 上面的某些属性不是必要的,如果没有对应的命令,可以省略(但启动命令不能省略),但省略之后就不能使用与该属性相关联的命令。比如,如果应用没有定义重新加载命令,则属性 ExecReload 可以省略,但同时不能使用命令 systemctl reload myapp


  4. 关闭 SELinux。这样做是为了防止服务开机自启动时发生权限不足而启动失败。关于这个报错更多的信息,可见笔者的另一篇博客:

    解决RHEL服务自启动时报错service Failed to locate executable…Failed at step EXEC spawning…Permission denied:
    https://blog.csdn.net/wangpaiblog/article/details/131628261

    关闭 SELinux 的方法是修改文件 /etc/selinux/config,将其中的属性 enforcingenforcing 改为 disabled。然后重启 Linux 即可。

    在这里插入图片描述

  5. 依次输出以下命令设置 myapp 开机自启动:

    systemctl daemon-reload

    systemctl enable myapp.service

  6. 重启电脑试一下是否真正成功。输入以下命令重启电脑:

    reboot

    重启后,马上输入以下命令:

    netstat -na | grep 该应用的端口号

    如果输出了端口号被使用的信息,说明 myapp 已经启动。

猜你喜欢

转载自blog.csdn.net/wangpaiblog/article/details/132137332