Ubuntu Server 16.04通过crontab开机自动运行需sudo权限脚本
我明白你遇到的困扰了——手动跑/home/user/ini.sh一切正常,但用crontab配置开机自启就是没效果。核心问题其实有两个:一是crontab的执行环境和你登录后的shell环境差异很大,很多必要的环境变量没加载;二是脚本里调用的sudo命令需要交互输入密码,而crontab运行时根本没有终端来接收输入。下面给你两种靠谱的解决方案:
方案一:改进crontab配置 + sudo免密授权
1. 配置sudo免密执行相关脚本
首先得让你的用户不用输密码就能执行脚本里调用的sudo命令,这样crontab运行时才不会卡在密码输入这一步。
一定要用visudo编辑sudoers配置文件(直接编辑容易因语法错误搞崩sudo功能):
sudo visudo
在文件末尾添加一行(把user换成你的实际用户名,把/path/to/sudo_script1.sh这类路径替换成ini.sh里调用的所有需要sudo权限的脚本路径):
user ALL=(ALL) NOPASSWD: /path/to/sudo_script1.sh, /path/to/sudo_script2.sh, /home/user/ini.sh
保存退出(按Ctrl+O回车确认,再按Ctrl+X退出)。
2. 修正crontab的启动命令
之前的crontab配置大概率因为环境变量缺失导致脚本执行失败,我们需要让crontab以登录shell的方式运行脚本,加载完整的环境变量。
编辑你的用户crontab:
crontab -e
替换原来的配置行,添加:
@reboot /bin/bash -l -c "/home/user/ini.sh"
参数解释:
-l:让bash以登录shell模式启动,会加载~/.bash_profile、~/.bashrc等配置文件,保证脚本需要的环境变量都能获取到-c:后面跟着要执行的脚本完整路径
保存退出后,重启系统测试是否生效。
方案二:用systemd服务(更稳定可靠)
Ubuntu 16.04已经默认使用systemd作为初始化系统,用systemd服务管理开机自启脚本比crontab更可靠,也更容易排查问题。
1. 创建systemd服务文件
创建一个名为ini-script.service的服务文件:
sudo nano /etc/systemd/system/ini-script.service
粘贴以下内容(替换user为你的实际用户名):
[Unit] Description=Auto-run initialization script on boot After=network.target # 如果脚本依赖网络,保留这行;不需要可以删掉 [Service] User=user ExecStart=/bin/bash /home/user/ini.sh Type=oneshot # 表示脚本只执行一次 RemainAfterExit=yes # 标记服务为已启动状态,即使脚本执行完毕 [Install] WantedBy=multi-user.target # 多用户模式下启动服务
保存退出(Ctrl+O回车确认,Ctrl+X退出)。
2. 启用并测试服务
先给服务文件设置正确的权限:
sudo chmod 644 /etc/systemd/system/ini-script.service
启用服务(设置为开机自启):
sudo systemctl enable ini-script.service
可以先手动启动服务测试是否正常运行:
sudo systemctl start ini-script.service
检查服务状态,确认没有错误:
sudo systemctl status ini-script.service
如果状态显示active (exited),说明脚本执行成功,之后重启系统就能自动运行了。
额外注意事项
- 确保
ini.sh本身有可执行权限:chmod +x /home/user/ini.sh - 脚本里所有的文件路径都要用绝对路径,比如别写
./subscript.sh,要写/home/user/subscript.sh——因为crontab或systemd的工作目录不是你的用户home,相对路径会找不到文件 - 如果脚本依赖特定的环境变量,除了用登录shell加载,也可以在脚本开头手动export需要的变量
内容的提问来源于stack exchange,提问作者user1156544

