Crontab和Linux日期相关的tips

好久没有在Javaeye上写东西了,今天碰到一个Linux下schedule任务的问题,记录一下。

crontab分系统级和用户级,系统级的crontab配置文件在/etc/crontab,crontab预定义的定时任务类别分别有:
/etc/crontab.hourly,
/etc/crontab.daily,
/etc/crontab.weekly,
/etc/crontab.monthly,
/etc/crontab.yearly(or crontab.annually),
/etc/crontab.reboot

/etc/crontab文件定义了crontab运行时系统变量,和已启用的定时任务:

[quote]SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
HOME=/

# run-parts
01 * * * * root run-parts /etc/cron.hourly
02 4 * * * root run-parts /etc/cron.daily
22 4 * * 0 root run-parts /etc/cron.weekly
42 4 1 * * root run-parts /etc/cron.monthly[/quote]

crontab定时器的命名规则如下:

# .---------------- minute (0 - 59)
# | .------------- hour (0 - 23)
# | | .---------- day of month (1 - 31)
# | | | .------- month (1 - 12) OR jan,feb,mar,apr ...
# | | | | .----- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# | | | | |
# * * * * * command to be executed

Note: [i]利用/可以定义repeatable任务,如将值“*/2”赋给minute位置,则会每两分钟执行一次。[/i]

今天碰到的问题来了:
我要跑一个脚本,脚本日志加上时间戳之后就重定向到日志文件了,所以crontab command就如下:
/home/ec2-user/upload.sh 2>&1 | while read line; do printf "$(date '+%F %T %z')\t$line\n"; done >>/home/ec2-user/upload.log 2>&1

但是当我把crontab任务创建好溜达一圈回来发现收到很多root用户发来的mail:
[quote]
From: root@ip-10-122-246-207.ec2.internal (Cron Daemon)
To: ec2-user@ip-10-122-246-207.ec2.internal
Subject: Cron <ec2-user@ip-10-122-246-207> /home/ec2-user/upload.sh 2>&1 | while read line; do printf "$(date -u '+
Content-Type: text/plain; charset=UTF-8
Auto-Submitted: auto-generated
X-Cron-Env: <SHELL=/bin/sh>
X-Cron-Env: <HOME=/home/ec2-user>
X-Cron-Env: <PATH=/usr/bin:/bin>
X-Cron-Env: <LOGNAME=ec2-user>
X-Cron-Env: <USER=ec2-user>
Status: RO

/bin/sh: -c: line 0: unexpected EOF while looking for matching `''
/bin/sh: -c: line 1: syntax error: unexpected end of file
[/quote]
这个mail很是让人不解,开始以为crontab的任务命令有长度限制,经过一番折腾和搜索crontab官方文档,却发现如下解释:
[quote]
A <percent-sign> character in this field shall be translated to a <newline>. Any character preceded by a <backslash> (including the '%' ) shall cause that character to be treated literally. Only the first line (up to a '%' or end-of-line) of the command field shall be executed by the command interpreter. The other lines shall be made available to the command as standard input.
[/quote]
原来字符%是一个可被crontab识别的换行符,如此一来%之前的命令才会被执行到,而%之后(第二行)则属于第一行命令的输入参数。这才解释了上述问题。随改之。

改之但是还是得需要日志行加入timestamp,自定义的日期格式是不能用了(包含字符%),故查看date的spec,可以用预定义的几种日期个是进行替换,
比如date -R会采用RFC 2822日期格式进行输出: Fri, 26 Nov 2010 14:31:33 +0000
而date --iso-8601='minutes'则会采用iso-8601日期格式(精确到分钟)来输出: 2010-11-26T14:33+0000

总结一下:Linux下的各种命令/机制必须得一个一个去钻研才能找到突破口,哪怕只是一点很容易被忽略的细节。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值