在crontab中使用$(date+ %Y%m%D)的引发的问题

问题原因

前几天有个定时任务执行经常出现问题,开发有没有执行日志,查看/var/log/cron定时任务执行日志,到了执行时间也确实执行了命令,但是没有执行结果,开发说能不能把执行结果展示出来,我说没问题,首先在命令行测试一下,发现执行成功,于是在cron里添加了个重定向,命令如下:

xxxx > /var/log/check/$(date +\%Y\%m\%d)-check.log 2>&1

到了第二天,开发说定时任务依旧没有执行,我说我看看执行日志,发现 /var/log/check/没有定义好的check.log,这下郁闷了,压根没有执行,但是/var/log/cron却显示执行了,实际是执行失败,按照我的理解,即使后面的重定向命令执行失败,是不会影响前面的命令执行的,现实是前面的命令确实没有执行,为了验证,我又在在测试服务期又做了一遍测试,随便写了个命令,按照上面的格式添加了crontab,定时任务依旧没执行,这下妥妥的打脸了,当时还给开发保证,cron命令写的没错,于是百度查找原因,找到了一篇文章:】

Cron job with $(date) command and redirect won’t run

里面在Best answer里有个回答:
I’m not sure how I missed this before but you are using a bash syntax for creating a subshell to run your command in. Since cron is not bash, this won’t work.
原因是你使用了shell,但是cron并不是shell,所以它无法工作。按照Linux命令的执行规则,执行命令是首先执行最右边的子shell,如果子shell执行失败,前面的则不会在执行。而$(date +\%Y\%m\%d)恰恰是个子shell,所说义执行失败
同时作者给了正确的写法:

0   20  *   *   *   /data/code/scripts/foo.sh >/root/foo.`date +\%Y-\%m-\%d-\%T`.log 2>&1

按照文章提示的方法,重新改写,果然执行成功,并且给出来了具体的错误原因,开发修改后,测试了几次,没在出问题。

总结

  • 做任何事话不要说死;
  • 认真测试;
  • 做好笔记;
### Ubuntu 16.04 自动化管理脚本实现指南 #### 一、Shell脚本基础框架 创建公共脚本 `/usr/local/bin/admin_common.sh` 作为基础模块: ```bash #!/bin/bash # 严格模式设置 set -euo pipefail IFS=$'\n\t' # 全局配置 LOG_DIR="/var/log/admin" BACKUP_DIR="/backups" mkdir -p "$LOG_DIR" "$BACKUP_DIR" # 日志记录函数 log() { local timestamp=$(date +'%Y-%m-%d %H:%M:%S') echo "[$timestamp] $1" | tee -a "$LOG_DIR/admin.log" } ``` #### 二、核心功能实现 ##### 1. 文件备份脚本 (`/usr/local/bin/backup.sh`) ```bash #!/bin/bash source /usr/local/bin/admin_common.sh # 生成带日期的备份文件名 backup_file="backup-$(date +%Y%m%d).tar.gz" source_dir="/data" log "开始备份: $source_dir → $BACKUP_DIR/$backup_file" tar -czf "$BACKUP_DIR/$backup_file" "$source_dir" 2>> "$LOG_DIR/error.log" # 添加校验和 (cd "$BACKUP_DIR" && sha256sum "$backup_file" > "${backup_file}.sha256") # 清理旧备份(保留7天) find "$BACKUP_DIR" -name "backup-*.tar.gz" -mtime +7 -delete log "备份完成,大小: $(du -h "$BACKUP_DIR/$backup_file" | cut -f1)" ``` ##### 2. 目录清理脚本 (`/usr/local/bin/clean.sh`) ```bash #!/bin/bash source /usr/local/bin/admin_common.sh target_dir="/tmp/clean_target" max_age=30 # 保留天数 # 安全验证 if [[ ! -d "$target_dir" || "$target_dir" == "/" ]]; then log "错误:无效目录 $target_dir" exit 1 fi log "清理目录: $target_dir (保留${max_age}天内文件)" find "$target_dir" -type f -mtime +$max_age -exec rm -v {} \; 2>> "$LOG_DIR/error.log" ``` ##### 3. 系统监控脚本 (`/usr/local/bin/monitor.sh`) ```bash #!/bin/bash source /usr/local/bin/admin_common.sh # 磁盘监控(阈值%) disk_threshold=80 disk_usage=$(df -h / | awk 'NR==2 {gsub("%","",$5); print $5}') if (( disk_usage > disk_threshold )); then log "警告: 磁盘使用${disk_usage}% > ${disk_threshold}%" fi # 内存监控 mem_usage=$(free -m | awk 'NR==2{printf "%.2f", $3*100/$2}') log "内存使用率: ${mem_usage}%" # 服务监控 check_service() { if ! systemctl is-active --quiet "$1"; then log "服务异常: $1 未运行!" fi } check_service nginx check_service mysql ``` #### 三、crontab定时任务配置 ```bash # 编辑root用户的crontab sudo crontab -e # 添加以下内容(注意设置PATH变量) PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin # 每日凌晨2点备份 0 2 * * * /usr/local/bin/backup.sh # 每30分钟监控系统 */30 * * * * /usr/local/bin/monitor.sh # 每周一凌晨3点清理 0 3 * * 1 /usr/local/bin/clean.sh # 日志轮转(每天) @daily find /var/log/admin -name "*.log" -mtime +7 -delete ``` #### 四、调试与优化技巧 1. **crontab调试方法**: ```bash # 查看cron执行日志 tail -f /var/log/syslog | grep cron # 测试模式运行 echo "==== DRY RUN ====" | tee -a "$LOG_DIR/admin.log" tar -ztvf "$BACKUP_DIR/$backup_file" | head ``` 2. **环境变量问题解决方案**: ```bash # 在脚本开头显式设置PATH export PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin ``` 3. **日志轮转配置**: 创建 `/etc/logrotate.d/admin_logs`: ``` /var/log/admin/*.log { daily missingok rotate 30 compress delaycompress notifempty create 644 root root } ``` #### 五、安全增强措施 1. **权限控制**: ```bash sudo chown root:root /usr/local/bin/*.sh sudo chmod 700 /usr/local/bin/*.sh sudo chmod 644 /var/log/admin/* ``` 2. **敏感操作确认**(在清理脚本中添加): ```bash if [[ -t 0 ]]; then # 仅在终端运行时询问 read -p "确认清理 $target_dir? (y/n) " -n 1 -r if [[ ! $REPLY =~ ^[Yy]$ ]]; then exit 1 fi fi ``` 3. **备份验证**: ```bash # 添加恢复测试函数 verify_backup() { (cd "$BACKUP_DIR" && sha256sum -c "${backup_file}.sha256") tar -ztf "$BACKUP_DIR/$backup_file" >/dev/null } ``` > **关键提示**:Ubuntu 16.04中cron环境与终端环境不同,务必在脚本中完整设置PATH变量 怎么运行
06-27
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值