alphanumeric
Posts: 2670
Joined: Tue Jan 19, 2016 2:17 pm
Location: Sydney, Nova Scotia, Canada

python file won't run on boot from crontab

Wed Jun 10, 2020 10:47 pm

I have done the sudo crontab -e and added the following line

Code: Select all

@reboot python3 /home/pi/scroll_clock.py &  
But It doesn't run on boot up. I have done this many times in the past and it worked fine?
If I run

Code: Select all

python3 /home/pi/scroll_clock.py
from a terminal window it runs fine. Launching it from idle also works.

Raspberry Pi Zero running the latest Raspberry Pi OS with a Unicorn Hat Mini attached.
The following code displays the day, date, time in a repeating scrolling message. The brightness up down works as does the shutdown when button X is pressed.

Code: Select all

#!/usr/bin/env python3
import sys
import os
import time, datetime
import RPi.GPIO as GPIO

from PIL import Image, ImageDraw, ImageFont
from unicornhatmini import UnicornHATMini

unicornhatmini = UnicornHATMini()

GPIO.setmode(GPIO.BCM)  
GPIO.setwarnings(False)
GPIO.setup(5, GPIO.IN, pull_up_down = GPIO.PUD_UP)
GPIO.setup(6, GPIO.IN, pull_up_down = GPIO.PUD_UP)
GPIO.setup(16, GPIO.IN, pull_up_down = GPIO.PUD_UP)

# button_map
#  5: "A",
#  6: "B",
# 16: "X",
# 24: "Y"}

X = 0



def Dim(channel):  
    unicornhatmini.set_brightness(0.5)

def Bright(channel):  
    unicornhatmini.set_brightness(1.0)

def Shutdown(channel):  
    global X
    X = 1    

GPIO.add_event_detect(5, GPIO.FALLING, callback = Dim, bouncetime = 2000)
GPIO.add_event_detect(6, GPIO.FALLING, callback = Bright, bouncetime = 2000)
GPIO.add_event_detect(16, GPIO.FALLING, callback = Shutdown, bouncetime = 2000)
#GPIO.add_event_detect(24, GPIO.FALLING, callback = Shutdown, bouncetime = 2000)

rotation = 180
if len(sys.argv) > 1:
    try:
        rotation = int(sys.argv[1])
    except ValueError:
        print("Usage: {} <rotation>".format(sys.argv[0]))
        sys.exit(1)

unicornhatmini.set_rotation(rotation)
display_width, display_height = unicornhatmini.get_shape()

print("{}x{}".format(display_width, display_height))

unicornhatmini.set_brightness(0.5)

font = ImageFont.truetype("5x7.ttf", 8)

offset_x = 0

while True:

    if offset_x == 0:
        text = time.strftime("%A %B %-d %-I:%M %p")
        text_width, text_height = font.getsize(text)
        image = Image.new('P', (text_width + display_width + display_width, display_height), 0)
        draw = ImageDraw.Draw(image)
        draw.text((display_width, -1), text, font=font, fill=255)
    else:
        
        for y in range(display_height):
            for x in range(display_width):
                if image.getpixel((x + offset_x, y)) == 255:
                    unicornhatmini.set_pixel(x, y, 0, 255, 0)
                else:
                    unicornhatmini.set_pixel(x, y, 0, 0, 0)

    offset_x += 1
    if offset_x + display_width > image.size[0]:
        offset_x = 0

    if X == 1:
        unicornhatmini.set_all(0, 0, 0)
        unicornhatmini.show()
        os.system("sudo shutdown now -P")
        time.sleep(30)

    unicornhatmini.show()
    time.sleep(0.05)

# Last edited on June 6th 2020
# added shutdown via button X
# also added Dim and Bright function to button A and B
# run sudo crontab -e
# add
# @reboot python3 /home/pi/scroll_clock.py &




pcmanbob
Posts: 10117
Joined: Fri May 31, 2013 9:28 pm
Location: Mansfield UK

Re: python file won't run on boot from crontab

Thu Jun 11, 2020 9:15 am

Try changing your cron line to this

Code: Select all

@reboot python3 /home/pi/scroll_clock.py >> /home/pi/error.txt 2>&1
then reboot your pi , hope fully you will have an error message in the file error.txt which will give you a clue as to why it stopped working.

As a side not you don't need the & at the end of a cron line, all programs run by cron are run in the background , even if you have multiple cron lines they will be run one after another without waiting for each program to complete.
We want information… information… information........................no information no help
The use of crystal balls & mind reading are not supported

alphanumeric
Posts: 2670
Joined: Tue Jan 19, 2016 2:17 pm
Location: Sydney, Nova Scotia, Canada

Re: python file won't run on boot from crontab

Thu Jun 11, 2020 11:01 am

Thank you I will try that. I was going to try again without then & at the end.

alphanumeric
Posts: 2670
Joined: Tue Jan 19, 2016 2:17 pm
Location: Sydney, Nova Scotia, Canada

Re: python file won't run on boot from crontab

Thu Jun 11, 2020 1:55 pm

Ok, the error is as follows

Code: Select all

Traceback (most recent call last):
  File "/home/pi/scroll_clock.py", line 58, in <module>
    font = ImageFont.truetype("5x7.ttf", 8)
  File "/usr/lib/python3/dist-packages/PIL/ImageFont.py", line 280, in truetype
    return FreeTypeFont(font, size, index, encoding, layout_engine)
  File "/usr/lib/python3/dist-packages/PIL/ImageFont.py", line 145, in __init__
    layout_engine=layout_engine)
OSError: cannot open resource
If I change
font = ImageFont.truetype("5x7.ttf", 8)
to
font = ImageFont.load_default()
My file runs from crontab. It looks awful on the LED Matrix, but it runs.
The font file 5x7.ttf is in the same folder as my file, and running my file from command line or from idle3 works OK.

alphanumeric
Posts: 2670
Joined: Tue Jan 19, 2016 2:17 pm
Location: Sydney, Nova Scotia, Canada

Re: python file won't run on boot from crontab

Thu Jun 11, 2020 2:34 pm

I found a solution, it looks like you need to include the path to the file.
I changed
font = ImageFont.truetype(“5x7.ttf”, 8)
to
font = ImageFont.truetype(“/home/pi/5x7.ttf”, 8)
and now it runs on boot. =)

pfletch101
Posts: 630
Joined: Sat Feb 24, 2018 4:09 am
Location: Buffalo, NY, USA

Re: python file won't run on boot from crontab

Thu Jun 11, 2020 9:50 pm

alphanumeric wrote:
Thu Jun 11, 2020 2:34 pm
I found a solution, it looks like you need to include the path to the file.
I changed
font = ImageFont.truetype(“5x7.ttf”, 8)
to
font = ImageFont.truetype(“/home/pi/5x7.ttf”, 8)
and now it runs on boot. =)
If you are running a script from crontab, it needs to include the full path to any file that it may need to access, since you cannot make any assumptions about where its home directory is.

GlowInTheDark
Posts: 1066
Joined: Sat Nov 09, 2019 12:14 pm

Re: python file won't run on boot from crontab

Thu Jun 11, 2020 10:21 pm

If you are running a script from crontab, it needs to include the full path to any file that it may need to access, since you cannot make any assumptions about where its home directory is.
This is FRN (*). First of all, the home directory is what it is. Regardless of where you are, your home directory is /home/pi. You can assume that. Always.

What I think you meant to say is that you cannot make any assumption about what the current directory is; that also is FRN. When a cronjob runs as user X, the current directory (unless/until changed by the job itself) is the home directory of X (often written: ~X). In our case, it will be /home/pi.

The confusion that results in people asserting this FRN is that the PATH in cronjobs is minimal compared to what it usually is (when one is running interactively). This leads people to the (often correct) assumption that they need to supply full paths on the programs they run (e.g., if you are running something that is stored in, say, /usr/games, you will need to specify /usr/games/whatever, since /usr/games in not in the default [minimal] PATH). This leads them to the incorrect assumption that *everything* needs a full path.

Note: I think (but am not certain, that is why I say "think") that fonts are looked up via a PATH sort of mechanism that, like the executable PATH mechanism, doesn't look in the current directory by default. This is probably why OP's problem occurred in the first place and why it went away when he full-path'd the font file. It is likely that using :./whatever.font would have worked as well.

Note also: I have not personally tested the @reboot functionality of crontab; I assume it works the same as regular cron jobs. If this is not the case - if, indeed, when you run via @reboot, it does indeed place you in some randomly determined directory on startup, then please let me know. I will update my files accordingly...


(*) Frequently repeated nonsense.
GitD's list of things that are not ready for prime time:
1) IPv6
2) 64 bit OSes
3) USB 3
4) Bluetooth

Loves Linux; loves to dance.

pfletch101
Posts: 630
Joined: Sat Feb 24, 2018 4:09 am
Location: Buffalo, NY, USA

Re: python file won't run on boot from crontab

Thu Jun 11, 2020 11:41 pm

GlowInTheDark wrote:
Thu Jun 11, 2020 10:21 pm
If you are running a script from crontab, it needs to include the full path to any file that it may need to access, since you cannot make any assumptions about where its home directory is.
This is FRN (*). First of all, the home directory is what it is. Regardless of where you are, your home directory is /home/pi. You can assume that. Always.
I said 'its home directory''. If you want to pick nits, 'current directory' is probably more correct, but not necessarily clearer to the novice.
What I think you meant to say is that you cannot make any assumption about what the current directory is; that also is FRN. When a cronjob runs as user X, the current directory (unless/until changed by the job itself) is the home directory of X (often written: ~X). In our case, it will be /home/pi.
You may or may not be right about @reboot cron jobs having the user's home directory as current directory. I didn't mean to imply that the current directory was random under these circumstances, just that you shouldn't (which would have been a better word than 'cannot') make assumptions about it. If you get into the habit of specifying full paths in scripts which you are developing to be run by cron (or systemd), you will not experience the 'my script runs at the command line but not in cron/systemd' problem which turns up in these forums at least once a week. If, on the other hand, you specify file names on the basis of assumptions about the current directory, and subsequently change how you are executing the script (user cron to different user cron or root cron; user cron to systemd unit) you will need to change all the file references, and I guarantee (from bitter experience) that you will frequently forget to do so.

GlowInTheDark
Posts: 1066
Joined: Sat Nov 09, 2019 12:14 pm

Re: python file won't run on boot from crontab

Fri Jun 12, 2020 5:46 am

I repeat: This is FRN.
GitD's list of things that are not ready for prime time:
1) IPv6
2) 64 bit OSes
3) USB 3
4) Bluetooth

Loves Linux; loves to dance.

User avatar
DougieLawson
Posts: 40167
Joined: Sun Jun 16, 2013 11:19 pm
Location: A small cave in deepest darkest Basingstoke, UK
Contact: Website Twitter

Re: python file won't run on boot from crontab

Fri Jun 12, 2020 10:03 am

GlowInTheDark wrote:
Fri Jun 12, 2020 5:46 am
I repeat: This is FRN.
Stop spouting this junk. Prove it or shut up!

If you don't know the current working directory you can't use relative file names. If you use full path names you won't go wrong (unless the file ownership prevents you).

With systemd cron (I've replaced anacron with that as I like the integration of cron with systemd)

Code: Select all

*/1 * * * * env 
gets

Code: Select all

Jun 12 10:52:06 ulysses env[4235]: LANG=en_GB.UTF-8
Jun 12 10:52:06 ulysses env[4235]: PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
Jun 12 10:52:06 ulysses env[4235]: HOME=/home/pi_u
Jun 12 10:52:06 ulysses env[4235]: LOGNAME=pi
Jun 12 10:52:06 ulysses env[4235]: USER=pi
Jun 12 10:52:06 ulysses env[4235]: SHELL=/bin/bash
Jun 12 10:52:06 ulysses env[4235]: INVOCATION_ID=96f2d69a40f94946a297ed890bac6005
Jun 12 10:52:06 ulysses env[4235]: JOURNAL_STREAM=8:589201
So python3 or any other program found in that path won't need a full path. The environment is more limited than your regular bash shell and it's running cron things with /bin/sh.

Code: Select all

*/1 * * * * pwd > /tmp/pwd
gets

Code: Select all

pi@ulysses:~ $ cat /tmp/pwd
/
pi@ulysses:~ $
so any file accessed by any script MUST have a full path.

Note: anacron may be different, so you may want to run your own tests.
Criticising any questions is banned on this forum.

Any DMs sent on Twitter will be answered next month.
All fake doctors are on my foes list.

Note: Any requirement to use a crystal ball or mind reading will result in me ignoring your question.

User avatar
thagrol
Posts: 3730
Joined: Fri Jan 13, 2012 4:41 pm
Location: Darkest Somerset, UK
Contact: Website

Re: python file won't run on boot from crontab

Fri Jun 12, 2020 12:15 pm

GlowInTheDark wrote:
Thu Jun 11, 2020 10:21 pm
If you are running a script from crontab, it needs to include the full path to any file that it may need to access, since you cannot make any assumptions about where its home directory is.
This is FRN (*). First of all, the home directory is what it is. Regardless of where you are, your home directory is /home/pi. You can assume that. Always.
Not true. The home directory is wherever the admins have put it. "/home/user" is the default convention but it doesn't mean it's "always" the case.

Edit: plus not every user has a home directory. End edit.
What I think you meant to say is that you cannot make any assumption about what the current directory is; that also is FRN. When a cronjob runs as user X, the current directory (unless/until changed by the job itself) is the home directory of X (often written: ~X). In our case, it will be /home/pi.
Possible correct but also irrelevant. The OP is talking about root's crontab so if you are correct it'll be /root not /home/pi
The confusion that results in people asserting this FRN is that the PATH in cronjobs is minimal compared to what it usually is (when one is running interactively). This leads people to the (often correct) assumption that they need to supply full paths on the programs they run (e.g., if you are running something that is stored in, say, /usr/games, you will need to specify /usr/games/whatever, since /usr/games in not in the default [minimal] PATH). This leads them to the incorrect assumption that *everything* needs a full path.
As already said, when you're not sure, use the full path to a file.
Note: I think (but am not certain, that is why I say "think") that fonts are looked up via a PATH sort of mechanism that, like the executable PATH mechanism, doesn't look in the current directory by default.
Unikely, there's no font path related environment variable set in any shell I'm using.
This is probably why OP's problem occurred in the first place and why it went away when he full-path'd the font file. It is likely that using :./whatever.font would have worked as well.
Nope. see above. Plus it's a python script accessing a font file directly not through the OS so any potential path mechanism wouldn't be used.
Note also: I have not personally tested the @reboot functionality of crontab; I assume it works the same as regular cron jobs. If this is not the case - if, indeed, when you run via @reboot, it does indeed place you in some randomly determined directory on startup, then please let me know. I will update my files accordingly...


(*) Frequently repeated nonsense.
As is much of your post.
Arguing with strangers on the internet since 1993.

bjtheone
Posts: 950
Joined: Mon May 20, 2019 11:28 pm
Location: The Frozen North (AKA Canada)

Re: python file won't run on boot from crontab

Fri Jun 12, 2020 12:37 pm

Biggest issues with cron are:

1) you get a stripped down environment. Often a different shell and much shorter path. You can address this by setting the shell and path to whatever you want and then running your script via cron.

2) using sudo. If you use the command "sudo crontab -e " you are editing root's crontab file. This will have a completely different environment that the user pi, and most certainly will not have a home directory of "/home/pi". If you want to run cron jobs as user "pi", the the command is "crontab -e" issued from a terminal logged in as user "pi".

Using fully qualified paths solves many issues with cron. It is not required, if you ensure the environment is correctly setup such that relative file references resolve as expected, and the correct programs are found, but it is a simple way to address the issue. The only downside is a bit more typing, and the potential that your crontab will not run the same way on another system if all the files you reference are not in the same places. However, for a novice user it is far and away the simplest solution.

bjtheone
Posts: 950
Joined: Mon May 20, 2019 11:28 pm
Location: The Frozen North (AKA Canada)

Re: python file won't run on boot from crontab

Fri Jun 12, 2020 4:24 pm

thagrol wrote:
Fri Jun 12, 2020 12:15 pm
GlowInTheDark wrote:
Thu Jun 11, 2020 10:21 pm
Note: I think (but am not certain, that is why I say "think") that fonts are looked up via a PATH sort of mechanism that, like the executable PATH mechanism, doesn't look in the current directory by default.
Unikely, there's no font path related environment variable set in any shell I'm using.
I suspect @GlowInTheDark is thinking about the FontPath used by X11 and by fontconfig. This allows you to define where it looks for font files. However, as noted, this would have nothing to do with how python finds a particular file.

User avatar
thagrol
Posts: 3730
Joined: Fri Jan 13, 2012 4:41 pm
Location: Darkest Somerset, UK
Contact: Website

Re: python file won't run on boot from crontab

Fri Jun 12, 2020 6:07 pm

bjtheone wrote:
Fri Jun 12, 2020 4:24 pm
thagrol wrote:
Fri Jun 12, 2020 12:15 pm
GlowInTheDark wrote:
Thu Jun 11, 2020 10:21 pm
Note: I think (but am not certain, that is why I say "think") that fonts are looked up via a PATH sort of mechanism that, like the executable PATH mechanism, doesn't look in the current directory by default.
Unikely, there's no font path related environment variable set in any shell I'm using.
I suspect @GlowInTheDark is thinking about the FontPath used by X11 and by fontconfig. This allows you to define where it looks for font files. However, as noted, this would have nothing to do with how python finds a particular file.
I did wonder. In which case it's irrelevant to cron too. Well unless you cronjob explictly needs it or X11 I guess.
Arguing with strangers on the internet since 1993.

Return to “Troubleshooting”