How to run a python script between a particular times every single day (on Linux)? - python-3.x

I am looking for a way to be able to run a python script at a particular times of day and then have it auto terminated at another time of day. Ideally, I would want this to not be done within the script itself.
For example: I would want the script to start at 08:00 and end at 10:00 then start again at 11:30 and then terminate at 15:00 and I would need this to happen every day automatically.
I have browsed through many suggestions online, and many of them suggested to use cron, however, as far as I can see, cron does not natively offer the functionality of automatically terminating an application.
Others have suggested using cron to start the application at a particular time and then use another cron instance to create a "terminate" file that the program will search for at every loop iteration and if the file is present then the python script will terminate via a sys.exit() function or something, however, this seems quite janky and more of a workaround than a real solution.

You may use Jobber. You will be able to start scripts whenever you want and for the time you want.
Warning : Jobber is not free. You can try it for free though.
Here is the link to Jobber's website.

You could write a script that creates a lockfile with cron (https://unix.stackexchange.com/questions/12815/what-are-pid-and-lock-files-for), and use the lockfile to know what the process ID is, then terminate the process with that id using cron as well

After you have determined that the process name is uniquely identifiable you could do something like this (that's indeed also using cron).
0 8 * * * /path/to/unique_name.py& ( echo "pkill unique_name.py" | at 10:00 )
30 11 * * * /path/to/unique_name.py& ( echo "pkill unique_name.py" | at 15:30 )
Edit 1:
And "name safe" versions (using kill).
0 8 * * * /path/to/unique_name.py& echo kill $! | at 10:00
30 11 * * * /path/to/unique_name.py& echo kill $! | at 15:30

Related

How to create cron job that is executing every 3 months?

I am using Hangfire in ASP.NET Core for Cron (recurring) Jobs, and I need to create a job that runs every three months starting from a given start date.
So if the start date was 15-Nov-2019, it should run on 15-Nov-2019, 15-Feb-2020, 15-May-2020 and so on and so forth.
And I need it to run every 3 months forever.
So I tried the following cron expression for this: "0 0 15 11/3 ?" or "0 0 15 11/3 *"
But after testing it on this translating site, it tells me that it will run on the following dates:
2019-11-15
2020-11-15
2021-11-15
2022-11-15
2023-11-15
So, if that is true, then how to make it run every three months starting from 15-Nov-2019 as described above and keep running forever?
The month field in cron takes a number between 1 and 12; depending on the cron implementation used, you could use an explicit list for the month field:
0 0 15 2,5,8,11 *
or a range with a step:
0 0 15 2-12/3 *
crontab.guru seems to support a single value with a step as well, but the crontab man page doesn't mention this style, so it might or might not work:
0 0 15 2/3 *
If you want to be able to set this up more than three months before you want it to run for the first time, you have to manually check the date; in shell (using GNU date), you would do something like this:
0 0 15 2-12/3 * [ $(date +%%s) -gt $(date -d '2019-11-01' +%%s) ] && yourcommand
This compares the current date to November 1st, 2019; if it is greater than that, the command is run.
Simple solution is to use the following command:
0 0 15 */3 *
It is very straight forward.Here's the output for your satisfaction from crontab.guru website
output of cron job

crontab settings with start_time and interval

I have a linux cron job to run. I want to configure its setting. What I have is, start_time for the job and interval after which it should repeat every time. interval is integer and has unit of day. So for example, I want to set up cron job starting on some random date in future and want to run that job periodically after every interval days. I tried to do 0 0 * * */interval but it does not give what I want. Any idea how to achieve it?
I think you may want something like
0 0 */interval * * /your/command
Basically switching day of week for day of the month. As for the random start date, that will have to be done somewhere else I think, like with a shell script which edits the cron file at a certain point etc.
EDIT:
This little script would allow you to edit the cron file.
#!/bin/sh
crontab -l > tempcron
echo "00 00 * * * /bin/ls" >> tempcron #just an example cron
crontab tempcron
rm tempcron

Cron Jobs Linux row deletion

I'm running this script;
$query = "SELECT * FROM XXX WHERE email='$Email'";
if($count==1) // fails
if($count==0) // succeeds
If successful
mysql_query ("INSERT INTO XXX (email) values ('$Email'");
Then proceeds onto the next script.
So, it checks to see if you have already ran this script in the past on that account, if you have your email is stored then you can't run this script ever again on that same email.
However, after this script has been processed I want it to delete the row created for the email after 6 hours.
So that after 6 hours they may run the script again.. I've been enlightened that I need to use Cron jobs for this, But I'm not sure how.. Any help is highly appreciated!
Many regards, and thanks in advance.
0 0,6,12,18 * * * /path/to/mycommand
This means starting from hour 0, 6, 12, and 18 the cron job would run. That would be the cron needed to do what you want.
Depending on which linux version you are running you will need to see how to actually create the cron job.
I would think at now +6 hours is a better choice here.

18 06,12,18 * * * what does this mean in cron issue time?

WHat does the following line mean in Linux - Chrone Time Scheduling
18 06,12,18 * *
Is it it will run 6.18 am, 12.18 pm and 6.18 pm every day for all month of all week.?
Check it out in manual page for crontab, either online or by typing man 5 crontab in terminal.
It means that the command will run at 6:18, 12:18 and 18:18 every day.
Also, I think you're missing one asterix (*) - there should be five time and date fields, and you've got only four (although, in post title, you've got five). Anyway, the full definition would look like:
18 06,12,18 * * *
You can test your cron job on cron job generator site page.
This is very helpful.
Just select whatever options you want for cron job and generate the code.

Handle "race-condition" between 2 cron tasks. What is the best approach?

I have a cron task that runs periodically. This task depends on a condition to be valid in order to complete its processing. In case it matters this condition is just a SELECT for specific records in the database. If the condition is not satisfied (i.e the SELECT does not return the result set expected) then the script exits immediately.
This is bad as the condition would be valid soon enough (don't know how soon but it will be valid due to the run of another script).
So I would like somehow to make the script more robust. I thought of 2 solutions:
Put a while loop and sleep constantly until the condition is
valid. This should work but it has the downside that once the script
is in the loop, it is out of control. So I though to additionally
after waking up to check is a specific file exists. If it does it
"understands" that the user wants to "force" stop it.
Once the script figures out that the condition is not valid yet it
appends a script in crontab and stops. That seconds script
continually polls for the condition and if the condition is valid
then restart the first script to restart its processing. This solution to me it seems to work but I am not sure if it is a good solution. E.g. perhaps programatically modifying the crontab is a bad idea?
Anyway, I thought that perhaps this problem is common and could have a standard solution, much better than the 2 I came up with. Does anyone have a better proposal? Which from my ideas would be best? I am not very experienced with cron tasks so there could be things/problems I could be overseeing.
instead of programmatically appending the crontab, you might want to consider using at to schedule the job to run again at some time in the future. If the script determines that it cannot do its job now, it can simply schedule itself to run again a few minutes (or a few hours, as it may) later by way of an at command.
Following up from our conversation in comments, you can take advantage of conditional execution in a cron entry. Supposing you want to branch based on time of day, you might use the output from date.
For example: this would always invoke the first command, then invoke the second command only if the clock hour is currently 11:
echo 'ScriptA running' ; [ $(date +%H) == 11 ] && echo 'ScriptB running'
More examples!
To check the return value from the first command:
echo 'ScriptA' ; [ $? == 0 ] echo 'ScriptB'
To instead check the STDOUT, you can use as colon as a noop and branch by capturing output with the same $() construct we used with date:
: ; [ $(echo 'ScriptA') == 'ScriptA' ] && echo 'ScriptB'
One downside on the last example: STDOUT from the first command won't be printed to the console. You could capture it to a variable which you echo out, or write it to a file with tee, if that's important.

Resources