1

I have a Python script that executes every minute on my Raspberry Pi. What I want to do now is that this infinite loop that repeats itself every minute, starts at an specific date that I can control, let's say in a month or on July 17th, whatever date I set. I have seen how to get today's date, but not to run something on an specific day and time.

This is the code that I have:

import schedule
import time

def job():
    #HERE IS WHERE I WRITE THE TASK


schedule.every(1).minutes.do(job)


while 1:
    schedule.run_pending()
    time.sleep(1)

What do you guys suggest?

6

Revised Answer:

After re-reading the question (2+ years later!) I've concluded my original answer may not have been the best answer. I've left the original answer (below), and adding this Edited answer.

Edited Answer:

In re-reading the question, it seems to me now that the OP's objective is to execute his code (a Python script) at an arbitrary time in the future; i.e. not on a repetitive schedule (á la cron), and not on a relative elapsed time from starting a program (á la datetime.timedelta class). This is not to say that the OP's objectives cannot be met with these methods, but there is a utility that seems perfectly suited to this objective: at

The at utility "executes commands at a specified time". It is not currently installed by default, so the first step is to install it:

$ sudo apt update && sudo apt upgrade
...
$ sudo apt install at

Scheduling with at is unconventional, but straightforward. man at provides a reasonable guide, and other useful docs are available. Two things to know before using at:

  1. all commands will be executed using /bin/sh

  2. output from commands goes to the user's mailbox by default

These need not be restrictive:

  1. Python (and other executable code/scripts) may be run from a shell script

  2. output may be redirected to a file - but not (easily) to stdout/terminal

For example, a Python script may be run using /bin/sh in (at least) two ways; consider the following examples:

1. Embedded in a shell script:

Create a script/file named MyShell.sh with "embedded" Python:

python3 - <<END
print('Hello, world!')
END

Schedule it using at:

$ chmod 755 MyShell.sh 
$ at -f /home/pi/MyShell.sh 13:30
warning: commands will be executed using /bin/sh
job 9 at Mon Aug 31 13:30:00 2020 

Anytime after this date & time, see the output in your mail spool:

$ mail

# ... , reading from the applicable message:

From: pi@raspberrypi4b.local
Date: Mon, 31 Aug 2020 13:30:00 -0000

Hello, world!
? q
$

2. Python script called from a shell script:

Assume the name of the Python script to be executed at some future time is MyPython.py:

#!/usr/bin/env python3
print('Hello from PythonWorld!')

We may create a shell script MyShell2.sh to run MyPython.py:

/usr/bin/python3 /home/pi/MyPython.py

To run MyShell2.sh on Oct 21, 2030 at 12:00 noon:

$ at -f /home/pi/MyShell2.sh 12:00 PM 10/21/2030  
warning: commands will be executed using /bin/sh
job 13 at Mon Oct 21 12:00:00 2030
$

As a "one-line" shell script, this can also run this as a command in at directly, and verified by atq:

$ at 12:00 PM 10/21/2030
warning: commands will be executed using /bin/sh
at> /usr/bin/python3 /home/pi/MyPython.py
at> <EOT>
job 14 at Mon Oct 21 12:00:00 2030

$ atq
14  Mon Oct 21 12:00:00 2030 a pi
$

Original Answer:

Use cron; it's designed for this. Trying to accomplish your objective in Python is like... I don't know, swatting flies with a sledgehammer? But that's strictly your choice of course.

cron is really quite easy to use, and the documentation is on your system:

man cron 
man crontab

Briefly, you'll edit your crontab as follows:

crontab -e

and you'll create a "schedule" for executing your Python program. Also, Debian (and therefore Raspbian) support non-standard schedules, including @reboot which runs a job/script/whatever when the machine reboots. Lots of online resources available for "hacking" cron:

2

You could try this if you want to incorporate the delay into your code:

import datetime
from time import sleep
import schedule

day_to_run = 10 # run this starting on the 10th
month_to_run = 5 # run this in may(the 5th month)

def job():
    #HERE IS WHERE I WRITE THE TASK

while 1:
    date = datetime.datetime.now()
    if date.day == day_to_run and date.month == month_to_run:
        break # this breaks out of the while loop if it's the right day.
    else:
        sleep(60) #wait 60 seconds

schedule.every(1).minutes.do(job) #continue with the rest of the program

while 1:
    schedule.run_pending()
    sleep(1)

Or you could use cron, as @Fabian says, which would schedule the script to run on a certain day:

en.wikipedia.org/wiki/Cron

https://kvz.io/blog/2007/07/29/schedule-tasks-on-linux-using-crontab/

running cron specific day of the month

Hope this helps!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.