Linux - GeneralThis Linux forum is for general Linux questions and discussion.
If it is Linux Related and doesn't seem to fit in any other forum then this is the place.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
I have a pretty good understanding how the crontab is formatted but have no idea how to write the cronjob entry to execute a script every 30 hours, is it even possible? Thanks.
I might be very wrong but I doubt that it's possible using cron. The range for the hour statement is 0-23 as far as I know. What you might do is write your own script and use the at command, don't know if that will work but if one can say:
Code:
at now +4 days
run_script
then it would be logical that you could say
Code:
at now +30 hours
since at works with a sort of timestamp when the at command was timed and calculates from there, where cron references to a time within a period (does this makes sence?).
If you could write your script with the at command (haven't tried it), then you could easily make it 'rewrite' itself every 30 hours when it ran.
Using at and submitting a new job from inside the script itself is a good idea. There is just a downside to take in account: if the machine is switched off for some reason at the time the job is scheduled, the at daemon will run the "expired" job at the successive boot up (this issue is discussed in a recent thread, here). If this happens the regular 30-hours scheduling is delayed and maybe this is an unwanted effect.
Another solution can be the following:
Code:
#!/bin/bash
REFTIME=1259449200
if [ $(date +%s) -ge $REFTIME ]
then
<your code here>
<...>
sed -i "/REFTIME=/s/$REFTIME/$((REFTIME+108000))/" $(readlink -f $0)
fi
This script records a reference time in seconds since epoch, which is the time at which the job is scheduled. The if/then construct checks if the current time is greater than or equal to the reference time and if the condition is matched it executes the code AND edits itself to update the reference time by 30 hours (it adds 108000 seconds to the reference time).
In this way you can run this job every 10 hours, using a crontab entry like
Code:
0 */10 * * * /path/to/the/script
and the block of code inside the if/then will be executed alternatively 1 time every 3. That is every 30 hours. Choose carefully the first reference time, that will be the actual time at which the cron job is executed for the first time, and the trick is done!
Edit: just thinking about the crontab entry... maybe even better is to run the script at fixed hours, so you can establish the starting reference time more precisely. Suppose you run the first job at midnight. Then adding 30 hours make the job to run at 6 of the next day, then at 12 of the day after and so on. Hence an entry like this
Code:
0 0,6,12,18 * * * /path/to/script
should be enough and you can easily determine the starting reftime using for example
Code:
date -d "20091129 00:00:00" +%s
Last edited by colucix; 11-27-2009 at 06:24 PM.
Reason: Suggested alternative crontab entry
unfortunately re-reading this thread after your reply... I realized the same downside is in the crontab method suggested: if the computer is down at the scheduled time, the script is not updated. I have to rethink about it. Thanks.
Wouldn't it be possible to write output to a file when the script was executed successfully and then check the outputfile for the last runtime? If the outputfile isn't present or out of date then it's safe to assume that the script was not executed, and then a procedure has to be launched to reset the reference time. Of course the first time the outputfile has to be generated by hand since it will be checked when first run.
Just thinking out wild, but that might solve the problem no?
Yes, it might solve the problem. You have just to store the file somewhere and (over)write the date into it every time the script is executed (or better when the block of code inside an if/then construct is executed).
Here is an alternative, which simply checks the current date without reference time (except for unix time) and without external files:
Code:
#!/bin/bash
time=$(($(date +%s)/3600))
if awk -v time=$time 'BEGIN{exit time%30}'
then
<your code here>
<...>
fi
The computed time at the beginning of the script is the integer of the number of seconds since epoch expressed in hours. Here we take advantage of the fact that bash does not manage floating point numbers, hence the result of the division is a truncated integer. The integer is necessary to take into account the 1 or more seconds delay in the execution of the script (in respect of the exact scheduled time).
Then it simply checks if the number of hours since epoch is exactly a multiple of 30. The only and mandatory constrain is that you have to start the job at a time (since epoch) which is already a multiple of 30 hours.
The next (based on CET time zone, not UTC) useful start times are:
Code:
Sun Nov 29 13:00:00 CET 2009
Mon Nov 30 19:00:00 CET 2009
Thu Dec 3 07:00:00 CET 2009
if the machine uses UTC the starting point have to be recalculated.
In my example the crontab entry would be something like:
Code:
0 1,7,13,19 * * * /path/to/script
To avoid the aforementioned constrain, we can try to simply add (or substract) an offset from the computed time. Once the offset is carefully determined, we can start our cron job at every hour and minute, at our pleasure.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.