手把手教你设置Linux开机自动运行.sh脚本文件
你是不是也遇到过这样的问题:写好了自动化任务脚本,每次重启后还得手动执行一遍?或者想让某个服务、监控程序、数据采集工具在系统一启动就悄悄开始工作?别担心,这其实是个很基础但特别实用的Linux技能——让.sh脚本在开机时自动运行。本文不讲虚的,不堆概念,全程用最直白的语言、最贴近真实环境的操作步骤,带你从零完成配置。无论你是刚接触Linux的新手,还是习惯图形界面、对命令行还有点生疏的开发者,都能照着一步步做成功。
整个过程只需要四步:写一个能干活的脚本、给它执行权限、选对系统级启动入口、最后验证效果。我们不用改内核、不碰systemd复杂单元文件(除非必要),优先采用兼容性好、理解门槛低、Ubuntu/CentOS/Debian通用的方法。过程中会明确告诉你哪些操作是必须的、哪些可以跳过、哪些地方容易踩坑——比如为什么有些系统找不到rc.local,该换什么方案,怎么一眼判断是否生效。所有命令都经过实测,贴出来就能复制粘贴运行。
1. 先写一个真正能运行的.sh脚本
脚本不是写完就完事,它得“知道自己在哪”“知道要干什么”“出错了也不卡住”。我们不搞复杂逻辑,先做一个清晰、安全、可验证的小例子。
1.1 创建脚本文件并写入内容
推荐把脚本放在你自己的用户目录下,比如/home/你的用户名/scripts/。这样既安全(不用动系统目录),又方便管理。假设你的用户名是ubuntu,那就按下面操作:
mkdir -p /home/ubuntu/scripts cd /home/ubuntu/scripts nano auto_run_test.sh在编辑器里输入以下内容(注意:第一行必须是#!/bin/bash,不能多空格、不能写错):
#!/bin/bash # 记录脚本开始时间,方便验证是否真在开机时运行 echo "[$(date '+%Y-%m-%d %H:%M:%S')] Script started at boot" > /home/ubuntu/boot_log.txt # 模拟一个实际动作:创建一个测试文件 touch /home/ubuntu/hello_at_boot.txt # 再写点内容进去,证明脚本确实执行了 echo "Hello from auto-run script!" >> /home/ubuntu/boot_log.txt echo "System uptime: $(uptime)" >> /home/ubuntu/boot_log.txt关键说明
- 第一行
#!/bin/bash是“解释器声明”,告诉系统用 bash 来运行这个文件,缺一不可,也不能写成#!/bin/bash(中文感叹号 ❌)$(date ...)是命令替换,实时获取当前时间,比写死的时间戳更有说服力- 所有路径都用绝对路径(如
/home/ubuntu/...),因为开机时没有“当前目录”的概念,相对路径(如./output.txt)大概率会失败>>是追加写入,避免重复运行时覆盖日志;>是覆盖写入,适合只保留最新一次结果
保存退出(nano 中按Ctrl+O→ 回车 →Ctrl+X)。
1.2 验证脚本能否手动运行
别急着设开机启动,先确保它自己能跑通:
bash /home/ubuntu/scripts/auto_run_test.sh然后检查结果:
cat /home/ubuntu/boot_log.txt ls -l /home/ubuntu/hello_at_boot.txt如果看到时间戳、问候语和 uptime 信息,并且hello_at_boot.txt文件存在,说明脚本本身完全没问题。这一步省不得,很多后续失败,根源都在脚本没测就上。
2. 给脚本加上“能被执行”的权限
Linux 默认不会让一个普通文件当程序运行,必须显式赋予“可执行”权限。这不是可选项,是硬性要求。
chmod +x /home/ubuntu/scripts/auto_run_test.sh这条命令的意思是:“给这个文件增加‘执行’权限(x)”。它比chmod 777更安全、更精准——777是“所有人可读可写可执行”,存在安全隐患;而+x只加执行权,其他权限保持不变。
验证是否成功:
ls -l /home/ubuntu/scripts/auto_run_test.sh输出中应该能看到-rwxr--r--或类似字段,关键是第三位(用户权限组)是x。如果还是-rw-r--r--,说明没加成功,再执行一次chmod +x。
3. 选择并配置开机启动入口
Linux 系统启动时,会按顺序执行一系列初始化脚本。我们要找一个位置稳定、权限可控、兼容性广、且你有写入权限的地方。主流方案有两个,我们按推荐顺序介绍:
3.1 方案一:使用/etc/rc.local(推荐给大多数用户)
这是最经典、最直观的方式,尤其适合 Ubuntu 18.04 及更早版本、Debian、CentOS 7 等。它的优势是:逻辑简单(就是个 shell 脚本)、调试方便(直接运行就能模拟开机行为)、不需要懂 systemd。
检查系统是否支持 rc.local
先确认这个文件是否存在且可用:
ls -l /etc/rc.local- 如果显示
No such file or directory,说明系统默认没启用,需要手动创建(见下方“方案二”) - 如果显示类似
-rwxr-xr-x 1 root root ... /etc/rc.local,说明已存在且有执行权限,可以直接编辑 - 如果显示
-rw-r--r--(没有x),说明只有读写权限,需要先加执行权:sudo chmod +x /etc/rc.local
编辑 rc.local,加入你的脚本
用管理员权限打开编辑:
sudo nano /etc/rc.local你会看到一个模板,通常以#!/bin/sh -e开头。关键点来了:你的命令必须加在exit 0这一行之前,且必须用绝对路径调用脚本。
在exit 0上方插入这两行:
# Run custom startup script su -c "/home/ubuntu/scripts/auto_run_test.sh" -s /bin/bash ubuntu为什么用
su -c ...而不是直接写/home/ubuntu/...?
因为/etc/rc.local是以root用户身份运行的。如果你的脚本里有操作用户家目录(如写~/boot_log.txt)、访问用户专属服务(如 Docker socket),直接运行会因权限问题失败。su -c "...切换回你的普通用户ubuntu再执行,既安全又可靠。
把ubuntu替换成你自己的用户名即可。
保存退出。现在/etc/rc.local的末尾看起来应该是这样:
# By default this script does nothing. # Run custom startup script su -c "/home/ubuntu/scripts/auto_run_test.sh" -s /bin/bash ubuntu exit 03.2 方案二:当rc.local不可用时,用crontab @reboot(Ubuntu 20.04+ 推荐)
如果你用的是较新版本的 Ubuntu(20.04、22.04)或 systemd 主导的发行版,/etc/rc.local可能被禁用或根本不存在。这时,crontab的@reboot是更轻量、更现代的选择。
设置用户级开机任务
直接为你的用户添加一条 cron 任务:
crontab -e在打开的编辑器里,添加这一行(注意:前面是@reboot,后面是你的脚本绝对路径):
@reboot /home/ubuntu/scripts/auto_run_test.sh保存退出。crontab会自动加载新规则。
优势与注意
- 完全用户级,无需
sudo,不碰系统文件- 自动处理用户环境(PATH、HOME 等),脚本里用
~或cd ~都能正常工作- 注意:
@reboot是在用户登录前触发,所以它依赖于系统启动时该用户的 cron daemon 已就绪(绝大多数桌面和服务器环境都满足)- 如果脚本需要图形界面(如弹窗、调用 GUI 程序),此方案不适用,需用其他方式
4. 重启验证,看效果是否真实发生
配置完,别猜,直接验证。这是最关键的一步。
sudo reboot等待系统完全重启、登录进桌面或 SSH 后,立刻检查:
# 查看日志文件是否生成、内容是否正确 cat /home/ubuntu/boot_log.txt # 查看测试文件是否存在 ls -l /home/ubuntu/hello_at_boot.txt # (可选)快速确认脚本是否真的在开机时运行 grep "Script started" /home/ubuntu/boot_log.txt | head -n 1如果boot_log.txt里有带时间戳的记录,且hello_at_boot.txt存在,恭喜你,已经成功了!
4.1 常见问题排查清单(遇到失败时逐条对照)
| 现象 | 最可能原因 | 快速检查方法 | 解决办法 |
|---|---|---|---|
boot_log.txt完全没生成 | 脚本路径写错,或rc.local/crontab没生效 | sudo cat /etc/rc.local或crontab -l看配置是否在 | 重新检查路径、权限、语法(尤其exit 0位置) |
| 日志里只有时间戳,没有后续内容 | 脚本执行中途报错退出 | sudo journalctl -u rc-local.service(systemd 系统)或查看/var/log/syslog | 在脚本开头加set -e(遇错停止)和set -x(打印每行命令),重试后看哪行报错 |
hello_at_boot.txt权限是root创建的 | 脚本以 root 身份运行,没切回用户 | ls -l /home/ubuntu/hello_at_boot.txt | 改用su -c "...方式,或在脚本里加chown ubuntu:ubuntu /home/ubuntu/hello_at_boot.txt |
crontab @reboot不生效 | 用户 cron 服务未启用 | sudo systemctl status cron | sudo systemctl enable --now cron |
5. 进阶建议:让开机脚本更健壮、更实用
上面的流程足以解决 90% 的需求。但如果你打算长期用、或者部署到多台机器,这里有几个小技巧,能让你少走弯路:
5.1 脚本里加“防重复”机制
有些任务(如启动一个服务)不能运行两次。可以在脚本开头加一段检测:
#!/bin/bash # 检查是否已运行(用 PID 文件) PIDFILE="/home/ubuntu/scripts/auto_run_test.pid" if [ -f "$PIDFILE" ] && kill -0 $(cat "$PIDFILE") > /dev/null 2>&1; then echo "[$(date)] Already running, exit." >> /home/ubuntu/boot_log.txt exit 0 fi # 写入当前 PID echo $$ > "$PIDFILE" # ... 你的主逻辑在这里 ... # 退出前清理 PID 文件 rm -f "$PIDFILE"5.2 用 systemd 服务替代(适合生产环境)
虽然rc.local和crontab简单,但 systemd 服务才是现代 Linux 的标准做法。它提供日志追踪、依赖管理、自动重启等能力。如果你需要更高可靠性,可以这样创建一个服务:
sudo nano /etc/systemd/system/boot-script.service内容如下:
[Unit] Description=Run my startup script at boot After=multi-user.target [Service] Type=oneshot User=ubuntu ExecStart=/home/ubuntu/scripts/auto_run_test.sh RemainAfterExit=yes [Install] WantedBy=multi-user.target然后启用:
sudo systemctl daemon-reload sudo systemctl enable boot-script.service sudo systemctl start boot-script.service这不是必须的,但值得了解——它代表了更规范、更易维护的方向。
5.3 记录完整执行日志,方便排障
把脚本所有输出(包括错误)都记下来,比只看几个 echo 有用得多:
#!/bin/bash LOGFILE="/home/ubuntu/boot_script_full.log" exec >> "$LOGFILE" 2>&1 echo "[$(date)] Script started" # ... your commands ... echo "[$(date)] Script finished"获取更多AI镜像
想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。