2

I am trying to run a python script when my Raspberry pi 4 boots. THis python script works when I run it directly, with no errors. I have edited the crontab file to do this as can be seen below:

# Notice that tasks will be started based on the cron's system # daemon's notion of time and timezones. # # Output of the crontab jobs (including errors) is sent through # email to the user the crontab file belongs to (unless redirected). # # For example, you can run a backup of all your user accounts # at 5 a.m every week with: # 0 5 * * 1 tar -zcf /var/backups/home.tgz /home/ # # For more information see the manual pages of crontab(5) and cron(8) # # m h dom mon dow command @reboot python /home/pi/FUZEGUI.py > /home/pi/FUZEGUIlog.txt 

The log file has no information in it. I have tried a different method, rc.local;

# By default this script does nothing. # Print the IP address _IP=$(hostname -I) || true if [ "$_IP" ]; then printf "My IP address is %s\n" "$_IP" fi printf "Launching FUZE GUI" sudo python home/pi/FUZEGUI.py & exit 0 

But that doesn't work either. Script

#!/usr/bin/env python try: import Tkinter as tk except: import tkinter as tk from PIL import Image, ImageTk import time import threading root = tk.Tk() root.attributes('-fullscreen', True) root.geometry("800x800") # Define Canvas canvas = tk.Canvas(root, width=800, height=800) canvas.grid(row=0, column=0) # translates an rgb tuple of int to a tkinter friendly color code def _from_rgb(rgb): return "#%02x%02x%02x" % rgb # Called when user presses View Log button def viewLogRaise(): # Hide Previous Windows canvas.itemconfigure(logButtonWindow, state="hidden") canvas.itemconfigure(titleLabelWindow, state="hidden") # Open Closed Windows canvas.itemconfigure(backButtonWindow, state="normal") canvas.itemconfigure(logTextWindow, state="normal") canvas.itemconfigure(scrollbarWindow, state="normal") #I want to read the file continuously at this point. t =threading.Thread(target=readFile) t.start() def backToMenu(): # Hide Previous Windows canvas.itemconfigure(backButtonWindow, state="hidden") canvas.itemconfigure(logTextWindow, state="hidden") canvas.itemconfigure(scrollbarWindow, state="hidden") # Open Closed Windows canvas.itemconfigure(logButtonWindow, state="normal") canvas.itemconfigure(titleLabelWindow, state="normal") def follow(thefile,reading): count= 0 thefile.seek(0, 2) count += 1 while reading == True: line = thefile.readline() if not line: time.sleep(0.1) continue yield line def readFile(): logfile = open("fast.log", "r") loglines = follow(logfile,True) for line in loglines: logText.insert(tk.END, line) # Background pathToGif = "redpoly4.jpg" # red_background=Image.open("redBackground.gif") backgroundImage = ImageTk.PhotoImage(file=pathToGif) canvas.background = backgroundImage bg = canvas.create_image(0, 0, anchor=tk.NW, image=backgroundImage) titleLabel = tk.Label(root, fg="white", text="FUZE", borderwidth=2, relief="solid", bg=_from_rgb((239, 36, 37)), font=("Courier", 100)) titleLabelWindow = canvas.create_window(400, 120, window=titleLabel) logButton = tk.Button(root, fg="white", text="View Log", command=viewLogRaise, borderwidth=2, relief="raised", bg=_from_rgb((239, 36, 37)), font=("Courier", 46)) logButtonWindow = canvas.create_window(400, 320, window=logButton) backButton = tk.Button(root, fg="white", text="Back", command=backToMenu, borderwidth=2, relief="raised", bg=_from_rgb((239, 36, 37)), font=("Courier", 20)) backButtonWindow = canvas.create_window(70, 360, window=backButton) canvas.itemconfigure(backButtonWindow, state="hidden") logText = tk.Text(root, bg="white", height=22, width=60, borderwidth=2, relief="solid") logTextWindow = canvas.create_window(450, 208, window=logText) # attach text widget to scrollbar scrollbar = tk.Scrollbar(root) scrollbar.grid(row=1,column=3) scrollbarWindow = canvas.create_window(710,200, window=scrollbar) logText.config(yscrollcommand=scrollbar.set) scrollbar.config(command=logText.yview) canvas.itemconfigure(scrollbarWindow,state="hidden") canvas.itemconfigure(logTextWindow, state="hidden") root.mainloop() 
4
  • do you run it as a user or root? what does the cron log say? do you have MTA to see if there is an error somewhere?
    – kyjanond
    CommentedJun 18, 2020 at 16:13
  • At startup there is a minimal environment with no $PATH so you need to use the actual location of binaries for example /usr/bin/pythonCommentedJun 18, 2020 at 19:58
  • 1
    Does this answer your question? What are the relative merits of putting start-up process in cron vs. rc.local?
    – Milliways
    CommentedJun 19, 2020 at 0:53
  • When you say "doesn't work" and "log has no information in it", does that mean that your script runs and the log file gets created, but remains empty?CommentedJun 30, 2020 at 12:21

2 Answers 2

5

You've run into a well-known limitation with cron. The question has been asked and answered here many times. This recent example highlights the two (at least two) choices you have:

  1. use cron (older, simpler)
  2. use systemd (newer, more complex)

The answer to your question in the context of cron usage is this:

If your script runs from the command line, but fails to run from @reboot in your crontab, then put a sleep command before your other command; e.g.:

@reboot (sleep 15; <your command here>) 

You can also help yourself by redirecting your stderr stream to a file - otherwise any error messages encountered will go to the "bit bucket":

@reboot (sleep 15; <your command here>) >> /home/pi/cronjoblog.txt 2>&1 

>> /home/pi/cronjoblog.txt is a "redirection"; what goes to the screen, is re-directed to the specified file.

stderr is the "error stream" & is numbered "2" by convention

stdout is the "normal output", numbered "1" by convention

2>&1 is an obtuse way of telling your system that you want your error messages to be "merged" with your normal output.

    0

    If my understanding is correct, since you want this to occur prior to logging in (on boot) you will not have input your password to determine user/root, so i would remove the sudo in the argument.

    In rc.local, instead of sudo python ... & try inputting the full path to python. I had a similar issue, and this worked for me: sudo /usr/bin/python [PATH TO SCRIPT.py] &

    1
    • That didn't work for meCommentedJun 18, 2020 at 20:41

    Start asking to get answers

    Find the answer to your question by asking.

    Ask question

    Explore related questions

    See similar questions with these tags.