Ubuntu cron定时任务执行报错但网络正常的原因及脚本位置咨询
问题描述
背景
Ubuntu 20.04.1 LTS服务器网络偶尔异常,手动执行以下命令可恢复:
cp bak/bad.yaml 00-installer-config.yaml netplan apply cp bak/good.yaml 00-installer-config.yaml netplan apply cd ~/cmd ./nat.sh
自动化操作步骤
为避免人工干预,通过cron配置定时任务:
- 执行
crontab -e编辑root用户的定时任务 - 添加定时规则:
0 * * * * /etc/cron.d/netfix >> net_crontab 2>&1,每小时执行netfix脚本并输出日志 netfix脚本内容即为上述恢复网络的命令序列
异常现象
春节期间网络未出现异常,但查看net_crontab日志发现:
- 日志提示
netplan和iptables命令未找到 - 却显示
20230124 05:00:01 network ok和20230124 06:00:01 network ok
疑问
- 为何
netplan命令未找到,但6点时日志显示网络正常? netfix脚本放在/etc/cron.d是否合适?
补充信息
- root用户在bash中执行
which netplan可正常找到命令路径 netfix脚本恢复网络后未做检查,5点的network ok存疑
问题分析与解决建议
1. netplan命令未找到但日志显示network ok的原因
核心问题:cron环境变量与交互式bash不一致
cron运行时的PATH默认仅包含/usr/bin:/bin,而netplan这类系统管理命令通常在/usr/sbin目录下,不在cron的默认PATH中,导致执行脚本时找不到命令。但root用户的交互式bash会加载完整的环境变量,所以能正常找到netplan。
日志显示network ok的逻辑漏洞
脚本里的network ok是固定输出内容,没有真正做网络状态校验——不管脚本里的命令是否执行失败,都会打印这句话。而6点时网络本身就处于正常状态,并非脚本修复的结果,所以日志显示正常和脚本执行失败没有关联。
2. netfix脚本放在/etc/cron.d是否合适?
不合适。/etc/cron.d是专门存放定时任务配置文件的目录,不是存放可执行脚本的位置,符合规范的做法是将自定义脚本放到/usr/local/bin/这类用户自定义可执行文件目录。
修复与优化方案
方案一:在脚本中使用命令绝对路径
先通过root交互式bash执行which netplan和which iptables拿到命令的绝对路径,比如假设netplan路径为/usr/sbin/netplan,修改脚本:
cp bak/bad.yaml 00-installer-config.yaml /usr/sbin/netplan apply cp bak/good.yaml 00-installer-config.yaml /usr/sbin/netplan apply cd ~/cmd ./nat.sh
方案二:在脚本开头补全PATH环境变量
在netfix脚本最上方添加一行,把所需路径加入环境变量:
#!/bin/bash PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin # 以下是原脚本内容 cp bak/bad.yaml 00-installer-config.yaml netplan apply ...
方案三:修正脚本存放位置
- 移动脚本到规范目录并赋予执行权限:
mv /etc/cron.d/netfix /usr/local/bin/ chmod +x /usr/local/bin/netfix
- 修改crontab定时规则(建议日志文件用绝对路径,避免cron找不到目录):
0 * * * * /usr/local/bin/netfix >> /var/log/net_crontab.log 2>&1
额外优化:添加真实网络状态检查
在脚本末尾添加校验逻辑,让日志输出反映真实网络状态:
# 脚本末尾添加 if ping -c 3 8.8.8.8 > /dev/null 2>&1; then echo "$(date +%Y%m%d\ %H:%M:%S) network ok" else echo "$(date +%Y%m%d\ %H:%M:%S) network failed" fi
内容的提问来源于stack exchange,提问作者Yuankuan Zhang
相关产品推荐
相关产品推荐

