I have a Raspberry Pi 4 running Debian GNU/Linux 12 (bookworm)
I have a Python script in a shell file launcher.sh (with executable for all permissions) that runs happily without complaint if I initiate it from a remote ssh terminal:
#!/bin/sh
export DISPLAY=:0;/home/craign/main.py
main.py is:
#!/usr/bin/env python3
# sudo apt-get install feh (to show that I've installed feh)
import subprocess
import time
# Display the image
image = subprocess.run(["feh", "--hide-pointer", "-x", "-q", "-F", "-B", "black", "-g", "1280x800", "/home/craign/image.jpg"])
If I try to use cron to execute on boot with (this is sudo crontab -l):
@reboot sh /home/craign/launcher.sh >/home/craign/logs/cronlog 2>&1
In the log file I'm getting
feh ERROR: Can't open X display. It is running, yeah?
Which I don't get if I just run it straight from the default shell that I'm served when I ssh in to the Pi. So I think that somehow I'm not telling the startup script to know what correct environment I'm in.
How can I execute that launcher.sh script on boot so that it knows where the right DISPLAY environment variable points to? I'm not married to this system of using cron to start the program at boot. Any help around getting feh to use the display environment variable set, which is necessary, would be greatly appreciated.
-
@Milliways I did. Same error. Other ideas?Dribbler– Dribbler2024年07月21日 11:17:34 +00:00Commented Jul 21, 2024 at 11:17
2 Answers 2
Had a similar boot up problem where a Ubuntu Raspberry Pi failed to start the python application from a systemctl script because the X display had not yet started.
Consider starting a script which loops on testing if the X display has started and only starts the actual python application after detecting an active X display.
For example, a BASH script testing if openbox has started may look like this:
#!/bin/bash
# Check if openbox has started.
while [[ ! `pgrep -x openbox` ]];
do
sleep 1
done
...append code to this script to start your application. If necessary, change the name of the desktop from openbox to the desktop used.
-
Thanks so much for the suggestion @st2000! I'm not sure how to test if the X display has started--how would I do that?Dribbler– Dribbler2024年07月21日 22:51:30 +00:00Commented Jul 21, 2024 at 22:51
-
I've added an untested BASH script that should loop until a desktop called OPENVBOX is running. I would start your application in this script after this loop. Note, OPENBOX is not the default desk top for Debian. I believe GNOME is. So change the script accordingly.st2000– st20002024年07月22日 13:10:22 +00:00Commented Jul 22, 2024 at 13:10
I finally got this to work. It's not hard, but the solution ultimately was to do most of the environment work inside of the python code.
I used feh to display images. You should install feh with
sudo apt-get install feh
The python program to run is (obviously replace /home/craign/ with your own location):
#!/usr/bin/env python3
import os
import subprocess
import time
# Set the HOME environment variable
os.environ['HOME'] = '/home/craign' # Replace with the correct home directory
# Set the DISPLAY environment variable
os.environ['DISPLAY'] = ':0'
# Run xhost to allow X server access (you might need to install xhost: sudo apt-get install x11-xserver-utils)
subprocess.run(['xhost', '+local:'], check=True)
# Display the image
image = subprocess.run(["feh", "--hide-pointer", "-x", "-q", "-F", "-B", "black", "-g", "1280x800", "/home/craign/image.jpg"])
To run the program at boot:
sudo nano /etc/rc.local
Add this line before the exit 0 at the end of the file:
python3 /home/craign/main.py &
Of course make sure everything is executable.