New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Comments for Best practices for cron #79

Open
phinjensen opened this Issue Nov 11, 2017 · 10 comments

Comments

Projects
None yet
1 participant
@phinjensen
Contributor

phinjensen commented Nov 11, 2017

Comments for https://www.endpoint.com/blog/2008/12/08/best-practices-for-cron

To enter a comment:

  1. Log in to GitHub
  2. Leave a comment on this issue.
@phinjensen

This comment has been minimized.

Contributor

phinjensen commented Nov 11, 2017

original author: Jon Jensen
date: 2008-12-08T20:51:00-05:00

Those are excellent notes, Greg.

I heartily second the advice to test a cronjob a few minutes into the future -- it's a real waste to only find out the next day that the nightly job didn't run because cron's environment was different than your own shell, causing a failure.

I've found with vixie-cron, at least, that you have to schedule your test job at least 2 minutes in the future, or it won't run. This is apparently because cron reads jobs one minute in advance, so you need an extra padding minute to get your job in in time.

Speaking of environment, cron usually runs with a fixed PATH set in /etc/crontab, so what is the advantage of hardcoding the path of /usr/bin/psql vs. /bin/cp? Either one could show up somewhere else in the path, but at least on RHEL 5 both are safe without a full path because PATH is simply:

/sbin:/bin:/usr/sbin:/usr/bin

So it seems unless you know your program will be outside that path, there's no particular need to specify, is there? It doesn't hurt, but sometimes the extra noise makes the whole crontab harder to read.

On a similar note, it's helpful to use the fact that cron jobs run cd'd into the user's home directory, so no reason to specify a full path /home/$USER/bin/whatever when bin/whatever will do nicely and survive home directory moves as well.

I have to disagree with the suggestion that one should document the run times for each job. On several occasions I've had to track down crazy problems caused by the comment not matching up with the actual job specification, and others were tricked by it too. I think documenting the implementation (rather than the intent) falls into the category of "don't repeat yourself", and leads to "wrong documentation is worse than no documentation". I now just recommend anyone review "man 5 crontab" who doesn't know crontab syntax.

Do you have any complaints about the now quite common anacron, that lead to your liking fcron for rescheduling jobs?

@phinjensen

This comment has been minimized.

Contributor

phinjensen commented Nov 11, 2017

original author: Greg Sabino Mullane
date: 2008-12-10T16:26:00-05:00

so what is the advantage of hardcoding the path of /usr/bin/psql

I've been burned too many times with having to deal with multiple instances of the psql binary to not hardcode it these days. I agree that things like /bin/cp are overkill though. The noise of long paths is another reason I throw such things in ENVs at the top of the file.

I have to disagree with the suggestion that one should document the run times for each job. On several occasions I've had to track down crazy problems caused by the comment not matching up with the actual job specification, and others were tricked by it too

I still would rather have it spelled out explicitly. Not only does it make it easier to read for non-cron aware people, but it helps you to spot other people's mistakes. Forcing them to document what they think the line is doing is a good way to catch problems. I consider it a checksum. Any mismatch means they entered the specification wrong, cut-n-pasted the wrong entry, or just documented things incorrectly. Whatever the cause, it's a red flag that should be followed up on. I think it's worth the danger of readers relying solely on the documentation.

Do you have any complaints about the now quite common anacron, that lead to your liking fcron for rescheduling jobs?

I don't like that anacron is not a user-level tool. This makes fcron far superior in my book, as it seems to be a superset of both cron and anacron. Plus, it has some neat bells and whistles like 'serial' and 'erroronlymail'. Truthfully, I rarely use either one, but I suppose I should simply start promoting fcron rather than making a wishlist for cron. :) Thanks for the reply!

@phinjensen

This comment has been minimized.

Contributor

phinjensen commented Nov 11, 2017

original author: Gavin Satur
date: 2009-10-07T06:37:46-04:00

Greg, this is a very useful article. I've used cron for a while and have learned most of the stuff you mentioned through trial-and-error. I don't use full paths for binaries that are in the cron daemon's path. When using cron, it's always good to determine the environment used by cron (* * * * * env > some-file), given the different crons out there. I came across your blog while checking out if people version control their crontab files, as I believe it's a good practice and I'm introducing a structured way to do so (using SVN) within my Organization. Glad to see version control listed right at the top!

@phinjensen

This comment has been minimized.

Contributor

phinjensen commented Nov 11, 2017

original author: Slauticus
date: 2014-01-28T15:52:10-05:00

Where would you put scripts?

I added an entry in cron.hourly to call a script.sh. Where would you recommend putting the .sh?

@phinjensen

This comment has been minimized.

Contributor

phinjensen commented Nov 11, 2017

original author: Greg Sabino Mullane
date: 2014-01-29T10:23:06-05:00

Slauticus: if it is a simple script that is not used anywhere else, just put it directly into cron.hourly. Otherwise, a good place is /usr/local/bin.

@phinjensen

This comment has been minimized.

Contributor

phinjensen commented Nov 11, 2017

original author: Gregory Patmore
date: 2015-02-03T17:10:42-05:00

Interesting article Greg, I'm just curious why you suggest the script is better able to handle output direction then crontab?

I have gotten screwed over more by following that guideline then anything else regarding crontab. The basic gist of what happens is:

  1. Dev hands you a script that handles logging itself (classic dependency, even in well used utilities)

  2. You schedule the cron like a good little grunt

  3. Then you get a request or need to move the app to another server, or different OS, or change dir structures somehow

  4. Script then breaks because it was depending on a log path that isn't there.

  5. You request dev to change the script, which he happily agrees to.

  6. 6 months later, it hasn't risen to high enough priority for him to actually DO it.

  7. Ops manager says 'just fix it already for crying out loud'

  8. You either crack open the script and adopt another maintenance baby, or else more commonly, just symlink the darn thing and be done with it.

  9. 1 year later the team is standing around wondering how all these symlinks came to be and decide to take a whole sprint cleaning them up (which usually means just hard coding a new path, thus resetting the clock and the cycle starts anew)

--or--

  1. ops schedules the crontab and directs output to agreed place.
  2. you get a request to move the app somewhere that will break the output.
  3. you pop open crontab, change the place it's logging, save-quit
  4. done
@phinjensen

This comment has been minimized.

Contributor

phinjensen commented Nov 11, 2017

original author: Tyrel Denison
date: 2016-05-03T11:57:21-04:00

I realize this is a significantly older post, but I would love to know the script or cronjob that you created using RCS to diff your backups and email them to you. I have done some research and haven't found anything that seems to be able to accomplish that. Thanks for your input.

@phinjensen

This comment has been minimized.

Contributor

phinjensen commented Nov 11, 2017

original author: Greg Sabino Mullane
date: 2016-05-04T11:10:27-04:00

TD, glad you enjoyed this blast from the past. At this point, git has removed almost all of my RCS skills from my long-term memory, but I think it was something similar to this:

rcsdiff myfile >/tmp/diffy 2>&1 || mail -s 'myfile is a-changin' greg@example.com < /tmp/diffy

@phinjensen

This comment has been minimized.

Contributor

phinjensen commented Nov 11, 2017

original author: Walfroy Dauchy
date: 2017-04-07T20:45:32-04:00

Thanks for this very useful post ! I am looking for a way to make my cronjobs more readable through the use of aliases, so I am doing something like this :

sync='rsync -rvzmhtP --exclude=".*" --delete'
* * * * * $sync /foo /bar/

As it happens, rsync executes correctly with the options -rvzm.. and --delete, but --exclude=".*" is not read (does not provoke an error either). I get something like :

rsync: send_files failed to open "/foo/.bash_history": Permission denied (13) rsync error: some files/attrs were not transferred (see previous errors) (code 23) at main.c(1655) [generator=3.1.1]

I know that variable expansion does not work like in a real shell, but I don't know what to do. I've tried to escape the quotes and wildcard, to no avail.

Can you help me ? I'm using Vixie cron on Debian 8.

Thanks in advance.

@phinjensen

This comment has been minimized.

Contributor

phinjensen commented Nov 11, 2017

original author: Greg Sabino Mullane
date: 2017-04-19T15:52:40-04:00

Walfroy Dauchy, I wouldn't mix aliases and wildcards like that. Cron is fairly finicky and fragile, so in a case like that I'd write a small, clean shell script and just reference that. If it is well named, that will help a lot with readability (as will a comment in the cron file).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment