维护 cronjobs 和 shell 脚本的最佳实践?
我继承了一个庞大的 crontab,我需要维护和更新它。我对它或 bash 脚本没有太多经验(我认为我已经掌握了基础知识),但我想做好工作。 简短的请求:任何“重构”混乱的 crontab 和一组 bash 脚本的指南
长的请求:我遇到了很多问题,但是有这么多人使用 cron 文件等,我觉得我一定缺少一些大型存储库信息、最佳实践和工具 - 或者这只是此类编程的风格差异? (我的偏见:如果我可以使用工具更快、更一致、更好地完成某件事,为什么还要手动做某件事呢?)。
到目前为止的问题示例:
由于外部事件,crontab 有几天没有运行。我们与其他人一起手动浏览列表,试图找出哪些内容没有运行,哪些内容需要重新运行,以及哪些脚本需要编辑并运行较早的日期等。 我找不到的内容:
- 网上有很多(有点毫无意义的)“cron 生成器”。反面在哪里?我可以输入一个很长的 crontab、两个日期,并让它输出哪些进程应该在何时运行,或者总共运行多少次? 这似乎在我微薄的脚本能力之内,所以它不应该已经存在吗? ;)
- 或者,如果我必须再次这样做,是否有某种方法可以调用 bashscript,以便将 date() 的任何实例预先设置为较早的时间,而不是更改脚本中的每个日期调用? (例如所有错过的报告和账单发票)
事实证明,某个特定报告已经两年没有运行了。刚刚再次请求,瞧,它就在 crontab 中! bash 脚本只是破坏了相关文件的路径引用。 我找不到什么:bash 文件的某种路径检查器?就像网站链接检查器一样。是的,我最终将手动完成所有这些,但它会显示一些至少一些问题区域。
听起来有时,依赖进程之间的间隙要么太长要么太短,因此更新是在第一个进程运行后发生的,或者在调用第二个进程之前第一个进程尚未完成运行。我已经看到了一些可能的选项(例如 anacron 按顺序运行),但是您会推荐什么?
还有大量从 crontab 生成的本质上毫无意义的电子邮件(脚本抛出错误但运行“正确”,大多数情况下失败,或者只是打印非必要脚本的每一步)。我将手动检查脚本并尝试让它们提供更有用的数据,或者“悄悄地成功”,但是你知道 - 有什么指导方针吗?
如果我对问题的理解或布局感到困惑,那么我很抱歉,但是嘿 - 那么你看到我的问题了!我需要从新手开始,知道如何做才能做到这一点,而不是进一步搞砸敏感的系统。谢谢!
I have inherited a sprawling crontab that I need to maintain and update. I don't have much experience with it or bash scripting (I think I've got a decent grip on the basics) and I want to do a good job.
Short request: Any guidelines for 'refactoring' a messy crontab and set of bash scripts
Long request: I've run into a number of issues, but are so many people using cron files etc that I feel like I must be missing some large repository of information, best practices and tools - or is this just a stylistic difference for this kind of programming? (My bias: why do something manually if I can use a tool to do it faster, consistently and well?).
Examples of issues so far:
Due to an external event, the crontab didn't run for a couple of days. Along with someone else, we manually went through the list, trying to figure out what didn't run, what we needed to rerun, and what scripts we needed to edit and run with earlier dates etc.
What I can't find:- There are plenty of (slightly pointless) 'cron generators' online. Where are the reverse? Something I can feed in a long crontab, two dates, and have it output which processes should have run when, or just how many times total?
This seems within my meager scripting capabilities, so shouldn't it exist already? ;) - Alternatively, if I ever have to do that again, is there some way of calling a bashscript so that any instances of date() are pre-set to an earlier time, rather than changing every date call within the script? (e.g. for all the missed reports and billing invoices)
- There are plenty of (slightly pointless) 'cron generators' online. Where are the reverse? Something I can feed in a long crontab, two dates, and have it output which processes should have run when, or just how many times total?
It turns out a particular report hadn't been running for two years. It was just requested again, and lo, there it was in the crontab! The bash script just had broken path references to the relevant files.
What I can't find: some kind of path checker for bash files? Like a website link checker. Yes I'll be going through these all manually eventually, but it'd show up some at least some of the problem areas.It sounds like some times, there has either been too long or short a gap between dependent processes, so updates have happened after the first has been run, or the first hasn't finished running before the second has been called. I've seen a few possible options for this (eg anacron runs in sequential order), but what would you recommend?
There are also a large number of essentially meaningless emails generated from the crontab (scripts throwing errors but running 'correctly', failing mostly silently, or just printing everystep of non-essential scripts). I'll be manually going through scripts and trying to get them to provide more useful data, or 'succeed quietly', but y'know - any guidelines?
If my understanding or layout of the issue is confused, then I apologize, but hey - you see my problem then! I need to go from newbie, to knowing what to do to get this right, and not screw up a touchy system further. Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
不是完整的答案,但有更多有用的资源:
http://blog.endpoint.com/2008/12/best -practices-for-cron.html
我正在慢慢地经历这个,并尝试实现每一点。直到我发帖后,我才想到去谷歌搜索“最佳实践 cron”。 :P
对于版本控制,我将同时使用 RCS,因为我逐个文件地编辑脚本,但有人建议我设置 Git(或者如果我使用的是 Mercurial) Windows系统)。
这实际上听起来很棒:
http://everythingsysadmin.com/2010/09/xed-202-released.html
“xed 是一个 perl 脚本,它锁定文件,在文件上运行 $EDITOR,然后解锁它。”...并将其放入 RCS(如果尚未放入)。
完全无脑的版本控制。如果我了解 bash,我想创建一个编辑快捷方式,自动提交到我使用的任何版本控制系统。
我从系统管理员那里收到的其他提示,
日期:不要使用日期或 --date="last monday",而是使用固定日期并在每次运行时添加一天/一周等(如果显然不超过当天),因为如果脚本没有运行,我可以反复重新运行脚本,直到它跟上。啊!
(而且,这可能听起来很明显,但我最终将编辑大量报告,不要突出说报告运行的日期。将修复。)
并且放心我应该尝试并让 cron 电子邮件尽可能安静,这样我就能真正注意到是否有错误电子邮件。
有一些我尚未调查的更好的 cron 错误报告包装器,链接如下: http://habilis.net/cronic/
Not a full answer, but more resources that have been helpful:
http://blog.endpoint.com/2008/12/best-practices-for-cron.html
I am slowly going through this, and trying to implement each of the points. I hadn't thought to google 'best practices cron' til after my post. :P
For version control, I'm just going to use RCS in the meantime, as I edit scripts on a file-by-file basis, but I've been advised to get Git set up (or Mercurial if I was on a Windows system).
This actually sounds great:
http://everythingsysadmin.com/2010/09/xed-202-released.html
"xed is a perl script that locks a file, runs $EDITOR on the file, then unlocks it."...and puts it in RCS if it wasn't already.
Completely brainless version control. If I get my head around bash, I'd like to create an editing shortcut that automatically commits to whichever version control system I use.
Other tips I received from an System Admin,
Dates: Rather than using say, date, or --date="last monday", use a fixed date and add a day/week etc to it each time it runs (if not more than current day obviously), because then if the script doesn't run, I can just re-run the script repeatedly until it catches up. Ah!
(And, this might sound obvious, but heaps of the reports I'll be eventually edit, don't say prominently what dates the report is running for. Will fix.)
And was reassured I should try and get the cron emails as quiet as possible, so that I actually notice if there's an error email.
There are wrappers for better cron error reporting that I have not yet investigated, linked here: http://habilis.net/cronic/
艰巨的任务摆在你面前,祝你好运。 :)
我建议找到每天运行的所有任务,并将它们放入
/etc/cron.daily/
中自己的脚本中。与/etc/cron.weekly
中的每周、每小时和每月相同。如果机器并不总是在线,您可能想要研究使用
anacron(8)
来安排作业,但您仍然需要对作业的运行时间进行一定程度的控制。几年来,它一直是多个发行版的默认 cron-helper-tool,因此希望它足够稳定,可以依赖于您自己的任务;但我很容易想象它可能无法完全满足您的需求。在 Ubuntu 上至少可以使用两个软件包来将日期伪造为脚本:
datefudge
和faketime
。我对两者都没有经验,但听起来他们应该能够提供帮助。我希望你将来不再需要它。 :)抱歉,我知道 bash 脚本没有路径检查器。这似乎不太可能,因为简单的脚本很简单并且易于肉眼检查:)并且复杂的脚本无论如何都会在运行时生成它们的路径名。也许您可以保留每个脚本使用的路径名数据库,并编写一个新脚本来定期验证该数据库。
您可以通过设置 MAILTO="" 来禁用 cron 电子邮件。我不确定我喜欢这个。也许将
MAILTO
设置为仅记录帐户将有助于缓解洪流。另一种选择是真正熟悉您的procmail(1)
规则,这样您就可以将它们完全放入另一个邮箱中。擅长
mutt
color
或score
控件可以帮助您在谷壳中发现小麦。 (color index red black ERROR
或类似命令可能会帮助您更快地发现问题。)Herculean task ahead of you, best of luck. :)
I'd suggest finding all the tasks that run daily and shove them into their own scripts in
/etc/cron.daily/
. Same for weekly into/etc/cron.weekly
, hourly, and monthly.You might want to investigate use of
anacron(8)
for scheduling your jobs, if the machine won't always be online, but you still need some level of control over when the jobs are run. It's been the default cron-helper-tool for multiple distributions for a few years, so hopefully it's stable enough to rely on for your own tasks; but I could easily imagine that it might not perfectly meet your needs.Faking the dates to scripts can be done with at least two packages on Ubuntu:
datefudge
andfaketime
. I have no experience with either, but both sound like they should be able to help. I hope you won't need it in the future. :)Sorry, I know of no path-checker for bash scripts. It seems unlikely, since simple scripts are simple and easy to check by eye :) and complex scripts will be generating their pathnames at runtime anyhow. Maybe you could keep a database of pathnames used by each script and write a new script to verify that database regularly.
You could disable the cron email by setting
MAILTO=""
. I'm not sure I like this. Maybe settingMAILTO
to a logging-only account would help the deluge. Another option is getting really good at yourprocmail(1)
rules so you can stuff them in another mailbox completely.Getting good at
mutt
color
orscore
controls can help you spot the wheat amongst the chaff. (color index red black ERROR
or similar commands might help you spot the problems more quickly.)