Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Script to edit Crontab 1

Status
Not open for further replies.

HestonJames

Programmer
Aug 11, 2008
187
GB
Morning All,

I'm pretty much a total novice when it comes to shell scripting but hopefully you guys will be able to best advise me on how to achieve this.

I'm working on putting together a postinst script for a .deb package that gets run after files have been placed in locations around the system to finalize the installation.

For this particular application I need to make an entry into the root users crontab file. Now, on its own this might not seem like a very tricky task, the file is located:

/var/spool/cron/crontabs/root

and looks something like this:

# DO NOT EDIT THIS FILE - edit the master and reinstall.
# (/tmp/crontab.Wk9Ybr/crontab installed on Fri Sep 12 10:47:41 2008)
# (Cron version -- $Id: crontab.c,v 2.13 1994/01/17 03:20:37 vixie Exp $)
# m h dom mon dow command

The line I want to add to this crontab looks something like this:

* * * * * python /myapp/myapp.py > /myapp/output 2>&1

Now, the problem here lies in the fact that editing the file isnt actualy enough to install the modified crontab onto the system. Usualy, if doing this manualy you would open up the crontab using 'crontab -e' and make your changes, then when existing 'crontab -e' it installs the crontab for you.

Has anyone got any experiance of scripting crontab entries? Ideally I would also need a script which would reverse the entry and remove it, for uninstallation of the package.

I look forward to your suggestions guys,

Many thanks,

Heston
 
By 'scripting crontab entries' I'm assuming you mean automating the addition and deletion of entries? Really all you need is a script to edit the crontab, adding or deleting a # at the beginning of the appropriate line, then save it and activate it. Basically:

crontab -l > newcron.txt
Code:
crontab newcron.txt to activate the new crontab.

[i]I [b]want[/b] to be good, is that not enough?[/i]
 
Ken,

Thanks for the speedy response! This definitly looks like a very nice approach.

So, let me confirm that I understand what this is doing.

crontab -l > newcron.txt This copies the currently installed crontab contents into a file called newcron.txt?

crontab newcron.txt This activates the new crontab for the root user? correct?

How would you go about writing the delete entry code? I guess it'll need some form of regex to find our entry. I guess the simplest way to go about this will be to use some form of namespacing on all our entries, which perhaps use our company name or something. We can then perhaps find all lines in the crontab which contain 'mycompanyname' and remove them from the file?

Cheers Ken, I appreciate the advice.

Heston.
 
Hi Heston - pleased to help. No doubt others will be along with better ideas soon! My thoughts were you could use sed to do the change for you. Something like:

Create the copy of crontab:

crontab -l > copycron.txt

Create the sed script (sedscr) to make the change

/^test for crontab addition/c\
#test for crontab addition

(^ assumes the text starts at the beginning of the line)

This is then plugged into sed, applied to the output of crontab -l and the output written to a new file:

sed -f sedscr copycron.txt > newcron.txt

The new crontab is then activated:

crontab newcron.txt

You could and should test this of course! Leaving out the final step will enable you to examine newcron.txt for possible errors/ommisions.



I want to be good, is that not enough?
 
It's brutal but it works... (well, tested on AIX)
Code:
cat additions.txt >> /var/spool/cron/crontabs/root
kill $(ps -ef | awk '/cron/ && !/awk/ {print $2}')
On AIX, and, I believe all Unices, the cron process is relaunched when killed and, as it restarts, it re-reads the crontab.

On the internet no one knows you're a dog

Columb Healy
 
Hello Guys,

Thanks to both of your for your advice.

@ Columb, Your solution is certainly very neat code wise, however, I'm not sure its all that 'proper', like you say, its quite brutal, forcing it into restarting the cron process.

@ Ken, I've used sed a little in the past, I see what you're doing there, that certainly makes sense! However, how would you do the remove script? to remove the entry from the crontab? Could we use a similar method?

Cheers guys,

Heston
 
Hi Heston - I like columb's sledgehammer approach!

With my suggestion, we're not really removing the entry, just de-activating it (with the use of the # and a refresh of the crontab). As a consequence, to replace it, just reverse the lines in sedscr so that it would become:

/^#test for crontab addition/c\
test for crontab addition

Thereby removing the #. Again, the new crontab would have to be activated with crontab newcron.txt or whatever.






I want to be good, is that not enough?
 
In Solaris, cron can safely be restarted like this...
Code:
# Solaris 8, 9
/etc/init.d/cron stop ; /etc/init.d/cron start

# Solaris 10
svcadm restart cron
 
Morning All!

Sorry for the late reply, I've avoided work over the weekend and only just arived back in on a monday morning :)

These all look like great suggestions, I certainly appreciate the effort you've put into it.

I'm going to toy with these concepts and see what occurrs, I suspect it'll eventualy result in a combination of all to be honest, Sam, I like your method to restarting the cron, this is generaly how I would handle daemon restarts, we'll see how that works out.

Cheers all, I'll report back as soon as I have a working solution and you can give me a hand refining it :)

Cheers,

Heston
 
@Heston
If you have a script/tool to restart the cron on your OS, use it. As I am on AIX like Columb, I do it with killing cron too, as init just respawns it and there are no such scripts/tools (at least I never found any).
Btw. which OS are you using (didn't find it in the posts)?

laters
zaxxon
 
Zaxxon,

Thanks for that, I suspected the scripts were the best option. I'm running Debian, or a flavour there of.

Thanks,

Heston
 
Hi

Then note that the original [tt]cron[/tt] behavior is not optimal, so newer implementations works differently. Linux distributions may use such newer implementations. In some of them restarting [tt]cron[/tt] does not refresh the job list.

Feherke.
 
I got an Debian Etch 4.0 running - there is following script I would use (ie. same as SamBones on Solaris):
Code:
/etc/init.d/cron

Execute it and you see it's options.

laters
zaxxon
 
Do not have your package edit root's crontab when you install it.

Just have your package include a file in the [tt]/etc/cron.d[/tt] directory. That way, installing the package installs the cron job automatically, then it goes away gracefully when you uninstall. That's what that directory is there for.
 
Remember that the [tt]/etc/cron.hourly[/tt], [tt]/etc/cron.daily[/tt], [tt]/etc/cron.weekly[/tt], and [tt]/etc/cron.montly[/tt] directories are also available if they suit your needs.
 
Hello Guys,

Ok, seems I've been taught bad practices in the past, I've always just edited the root crontab :-s but this sounds like a nice idea.

Chipper, what sort of regularity can I have available to me on the cron.d? At the moment I have a script which runs every minute in the crontab, can I achieve that same effect using the cron.d directory?

Many thanks mate, I really appreciate that.

Heston
 
Sure. Files in the cron.d directory just contain [tt]/etc/crontab[/tt]-style lines, which specify a user in addition to the times and command. Given your above example, you'd simply have a file [tt]/etc/cron.d/myapp[/tt] that looks like:
Code:
* * * * *   [b]root[/b]   python /myapp/myapp.py > /myapp/output 2>&1

You may also want to specify environment variables (e.g. PATH or MAILTO) if you were relying on them being set differently in root's crontab.

(By the way, there's no need to restart Debian's cron when doing all this).
 
chipperMDW,

This is very cool stuff! very cool indeed!

This effectivly means I dont need a scripting process for this at all, as the DEB will automaticly place and remove the file from the directory tree anyway.

I'm going to play around with this later and see how it all works for me but this is VERY cool.

Thanks again mate,

Heston
 
Chipper Hi,

So I've given this ago and placed a file as you suggested in the cron.d directory however it doesnt appear to get run at all.

From looking around I'm wondering if this ie because the scripts dont inherit the environment variables, as you suggested. Tell me, which environment variables will I require to run my script as above? perhaps just the path to my python installation?

Sorry, thats a rather noobish linux question but environment variables arnt really anything I've played with before.

Cheers,

Heston
 
...and Linux isn't anything I've played with before Heston, so apologies if I led you up the garden path earlier.

It would be best to include the PATH and any other variables which the scripts have available when running interactively.

I want to be good, is that not enough?
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top