I have a raspberry pi python3 program "monitor.py" that works from the terminal
But it fails to run when I start it from boot.
Check status:
pi@raspberrypi:~ $ systemctl status monitor.service
● monitor.service - Service to start monitor in terminal on desktop
Loaded: loaded (/etc/systemd/system/monitor.service; enabled; vendor preset: enabled)
Active: failed (Result: exit-code) since Tue 2019-01-01 14:56:31 MST; 55s ago
Process: 624 ExecStart=/usr/bin/python3 /home/pi/monitor.py >> /home/pi/Desktop/monitor.log (code=exited, status=1/
Main PID: 624 (code=exited, status=1/FAILURE)
Jan 01 14:56:30 raspberrypi systemd[1]: Started Service to start monitor in terminal on desktop.
Jan 01 14:56:31 raspberrypi python3[624]: Traceback (most recent call last):
Jan 01 14:56:31 raspberrypi python3[624]: File "/home/pi/monitor.py", line 6, in <module>
Jan 01 14:56:31 raspberrypi python3[624]: **cf = open (cmdfile,"w")**
Jan 01 14:56:31 raspberrypi python3[624]: PermissionError: [Errno 13] **Permission denied: 'cmdfile.txt'**
Jan 01 14:56:31 raspberrypi systemd[1]: monitor.service: Main process exited, code=exited, status=1/FAILURE
Jan 01 14:56:31 raspberrypi systemd[1]: monitor.service: Unit entered failed state.
Jan 01 14:56:31 raspberrypi systemd[1]: monitor.service: Failed with result 'exit-code'.
Check for permissions:
pi@raspberrypi:~ $ ls -l cmdfile.txt
-rw-rw-rw- 1 pi pi 1 Dec 31 21:09 cmdfile.txt
pi@raspberrypi:~ $ ls -l monitor.py
-rwxrw-rw- 1 pi pi 506 Jan 1 09:50 monitor.py
pi@raspberrypi:~ $ ls -l /lib/systemd/system/monitor.service
-rwxr--r-- 1 root root 224 Dec 30 13:09 /lib/systemd/system/monitor.service
pi@raspberrypi:~ $ ls -l /home/pi/Desktop/monitor.log
-rw-r--r-- 1 pi pi 0 Jan 1 10:29 /home/pi/Desktop/monitor.log
The program monitor.py:
#!/usr/bin/python3
import time
cmdfile = "cmdfile.txt"
cf = open(cmdfile,"w")
cmd = 1
cf.write(str(cmd))
cf.close
isRunning = cmd
cntr = 0
wait = 10
while isRunning == cmd:
cntr += 1
print("Hello World:", cntr)
cf = open(cmdfile,"r")
cmd = int(cf.read())
cf.close
if isRunning != cmd:
print("check interrupt")
if cmd == 0:
import os
os.system("sudo reboot -h now")
else: # incremented
exit()
time.sleep(wait)
The systemctl monitor.service:
[Unit]
Description=Service to start monitor in terminal on desktop
Wants=graphical.target
After=graphical.target
After=multi-user.target
[Service]
User=pi
Type=idle
ExecStart=/usr/bin/python3 /home/pi/monitor.py &
[Install]
WantedBy=graphical.target
WantedBy=multi-user.target
Enable the new service:
pi@raspberrypi:~ $ sudo chmod 744 /lib/systemd/system/monitor.service
pi@raspberrypi:~ $ sudo systemctl daemon-reload
pi@raspberrypi:~ $ sudo systemctl enable monitor.service
Test the program:
pi@raspberrypi:~ $ ./monitor.py #note dot at start of the line
Hello World: 1
Hello World: 2
Hello World: 3
Restart:
pi@raspberrypi:~ $ sudo reboot
Check Status:
pi@raspberrypi:~ $ systemctl status monitor.service
Stop: (requires password)
pi@raspberrypi:~ $ systemctl stop monitor.service
Edit again with:
pi@raspberrypi:~ $ sudo systemctl --full edit monitor.service
Edit Note -- modified the above:
in monitor.service I changed the following.
Was:
ExecStart=/usr/bin/python3 /home/pi/monitor.py >> /home/pi/Desktop/monitor.log
Now:
ExecStart=/usr/bin/python3 /home/pi/monitor.py &
To remove the log (simplify) and add the & (to exit)
It still fails but there is one less thing to question.
&
is a very bad idea. Don't do that. The program is then completely out of control from systemd. If you want the behavior of traditional UNIX daemons then you must useType=forking
in Section [Service]. Seeman systemd.service
.