在工作中,我们经常有个需求,那就是在系统启动之后,自动启动某个脚本或服务。在 Windows 下,我们有很多方法可以设置开机启动,但在 Linux 系统下我们需要如何操作呢?
Linux 下同样可以设置开机启动,但可能需要我们敲一些命令(可能也有 UI 界面的设置方法,但我不熟,我更多是玩命令)。下面我们就介绍三种简单但可行的开机启动设置方法。
版权声明
本教程参考了One作者的教程,并结合自身实 际部署过程中积累的经验编写而成。原始教程链接为Linux 系统设置开机自动运行脚本的方法),感谢原作者提供的宝贵参考资料。
本教程仅供学习和交流使用,任何人不得将本教程的内容用于商业用途。如需引用或转载,请务必注明原作者及本文出处。如侵权之处,请联系博主进行删除,谢谢~
部分内容引用One大佬的教程,感谢大佬的贡献。
方法一:修改 /etc/rc.d/rc.local 文件
/etc/rc.d/rc.local 文件
会在 Linux 系统各项服务都启动完毕之后再被运行。所以你想要自己的脚本在开机后被运行的话,可以将自己脚本路径加到该文件里。
这种方法,在任何 Linux 系统上都可以使用。
- 环境:
CentOS Linux 7.9 (2009) (Core)
- 我们先来查看下这个文件的内容是什么
cat /etc/rc.d/rc.local
输出:
#!/bin/bash
# THIS FILE IS ADDED FOR COMPATIBILITY PURPOSES
#
# It is highly advisable to create own systemd services or udev rules
# to run scripts during boot instead of using this file.
#
# In contrast to previous versions due to parallel execution during boot
# this script will NOT be run after all other services.
#
# Please note that you must run 'chmod +x /etc/rc.d/rc.local' to ensure
# that this script will be executed during boot.
#创建一个空文件 /var/lock/subsys/local,该文件的存在通常用来指示某个服务或任务已经成功运行
#这是旧版 Linux 系统中的一种惯例,但在现代系统中,它的作用已经非常有限。
touch /var/lock/subsys/local
这个脚本是位于 /etc/rc.d/rc.local
的示例文件,主要用于兼容性目的,特别是在 CentOS 7 中。/etc/rc.d/rc.local
是传统的启 动脚本文件,允许用户在系统启动时执行自定义的脚本或命令,因此可以往里写开机要执行的命令或脚本。
/etc/rc.local
为/etc/rc.d/rc.local
的软链
- 可执行权限: 要确保这个脚本在系统启动时被执行,需要给脚本添加可执行权限:
chmod +x /etc/rc.d/rc.local
演示
- 首先,在根目录目录或指定的位置创建一个脚本文件,例如
/blog/start_all_containers.sh
:
vim /blog/start_all_containers.sh
- 添加脚本内容
#!/bin/bash
# 定义一个函数来启动所有未运行的Docker容器
start_stopped_containers() {
# 查找所有未运行的容器
stopped_containers=$(docker ps -a -f "status=exited" -q)
# 如果有未运行的容器,启动它们
if [ ! -z "$stopped_containers" ]; then
echo "启动所有未运行的Docker容器..."
docker start $stopped_containers
else
echo "没有未运行的Docker容器需要启动。"
fi
}
# 调用函数
start_stopped_containers
- 保存退出后,确保文件有执行权限
chmod +x /blog/start_all_containers.sh
- 然后,我们再将脚本添加到 /etc/rc.d/rc.local 文件最后一行:
vim /etc/rc.d/rc.local
/blog/start_all_containers.sh
添加后的内容:
#!/bin/bash
# THIS FILE IS ADDED FOR COMPATIBILITY PURPOSES
#
# It is highly advisable to create own systemd services or udev rules
# to run scripts during boot instead of using this file.
#
# In contrast to previous versions due to parallel execution during boot
# this script will NOT be run after all other services.
#
# Please note that you must run 'chmod +x /etc/rc.d/rc.local' to ensure
# that this script will be executed during boot.
touch /var/lock/subsys/local
#这里添加刚刚在/blog文件夹下创建的"start_all_containers.sh"脚本
/blog/start_all_containers.sh
- 直接重启系统验证测试:
reboot
可以看到开机自启动所有未运行的Docker容器,输出如下:
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ba8627412252 ruyu-blog-hd "java -jar /app/app.…" 37 hours ago Up About a minute 0.0.0.0:8088->8088/tcp, :::8088->8088/tcp ruyu-blog-hd
115838d43850 blog-ht "/docker-entrypoint.…" 2 days ago Up About a minute 80/tcp, 0.0.0.0:81->81/tcp, :::81->81/tcp blog-ht
3334358ca32b blog-qt "/docker-entrypoint.…" 2 days ago Up About a minute 0.0.0.0:80->80/tcp, :::80->80/tcp blog-qt
d14e0fc37e68 filesite/machete "/var/www/machete/do…" 2 days ago Up About a minute 0.0.0.0:445->445/tcp, :::445->445/tcp, 9000/tcp, 0.0.0.0:1081->80/tcp, :::1081->80/tcp machete
19abde9750b1 registry.cn-shenzhen.aliyuncs.com/mogublog_business/frpc "/bin/sh -c '/usr/bi…" 2 days ago Up About a minute frpc
e9f405df3cfe binaryify/netease_cloud_music_api "docker-entrypoint.s…" 4 days ago Up About a minute 0.0.0.0:3000->3000/tcp, :::3000->3000/tcp netease_cloud_music_api
de384f1f541f hitokoto/api "docker-entrypoint.s…" 4 days ago Up About a minute 0.0.0.0:8000->8000/tcp, :::8000->8000/tcp hitokoto_hitokoto_api_1
86e5cf8d6306 redis:6.0.8 "docker-entrypoint.s…" 4 days ago Up About a minute 6379/tcp hitokoto_hitokoto_db_1
6726bc097856 minio/minio "/usr/bin/docker-ent…" 4 days ago Up About a minute 0.0.0.0:9000-9001->9000-9001/tcp, :::9000-9001->9000-9001/tcp minio
d2c98432baa2 rabbitmq "docker-entrypoint.s…" 4 days ago Up About a minute 4369/tcp, 0.0.0.0:5672->5672/tcp, :::5672->5672/tcp, 5671/tcp, 15691-15692/tcp, 25672/tcp, 0.0.0.0:15672->15672/tcp, :::15672->15672/tcp rabbit
61da49911e67 redis:7.2.3 "docker-entrypoint.s…" 4 days ago Up About a minute 0.0.0.0:6379->6379/tcp, :::6379->6379/tcp redis
ec44863c383e mysql:8.0 "docker-entrypoint.s…" 5 days ago Up About a minute 0.0.0.0:3306->3306/tcp, :::3306->3306/tcp, 33060/tcp mysql
完成这些步骤后,脚本将在系统启动时自动运行,并尝试启动所有未运行的 Docker 容器。
- 有关 /etc/rc.d/rc.local 执行时机如下:
方法二:使用 crontab
这种方法,在任何 Linux 系统上都可以使用。
- 环境:
CentOS Linux 7.9 (2009) (Core)
crontab 是 Linux 下的计划任务,当时间达到我们设定的时间时,可以自动触发某些脚本的运行。
我们可以自己设置计划任务时间,然后编写对应的脚本。但是,有个特殊的任务,叫作 @reboot ,我们其实也可以直接从它的字面意义看出来,这个任务就是在系统重启之后自动运行某个脚本。
演示
下面是如何使用 crontab
来创建一个任务,以便定期启动所有未运行的 Docker 容器。
- 编写脚本
创建一个脚本文件,例如 /blog/start_stopped_docker_containers.sh
vim /blog/start_stopped_docker_containers.sh
并添加启动未运行的 Docker 容器的内容:
#!/bin/bash
# 定义一个函数来启动所有未运行的Docker容器
start_stopped_containers() {
# 查找所有未运行的容器
stopped_containers=$(docker ps -a -f "status=exited" -q)
# 如果有未运行的容器,启动它们
if [ ! -z "$stopped_containers" ]; then
echo "启动所有未运行的Docker容器..."
docker start $stopped_containers
else
echo "没有未运行的Docker容器需要启动。"
fi
}
# 调用函数
start_stopped_containers
- 保存退出后,确保文件有执行权限
chmod +x /blog/start_stopped_docker_containers.sh
- 编辑 crontab
使用 crontab -e
打开 crontab
编辑器,然后添加以下行:
crontab -e
在打开的编辑器中,添加以下行在每次系统启动时,执行 /blog/start_stopped_docker_containers.sh
脚本
@reboot /blog/start_stopped_docker_containers.sh
- 然后,直接重启即可。运行的效果跟上面类似。
reboot