Debian 9: autorun on boot with systemd does not work

Hello learned group,

I have a Python application that I’d like to see start up on boot. It uses Tkinter, so it needs the graphical environment.
Running: python /home/debian/eme/myprog.py from the QTerminal command line works as expected. Not outside the LXQT environment, which is normal I think.
I made a service file: myprog.service like this:
[Unit]
Description=to invoke myprog automatically on boot
Requires=graphical.target
[Service]
Type=simple
WorkingDirectory=/home/debian/eme/
ExecStart=python /home/debian/eme/myprog.py
[Install]
WantedBy=multi-user.target

Service file is located at both: /etc/systemd/system/ and /lib/systemd/system/ as I am unsure where it actually belongs. Of course I already spend a lot of time at internet to find a solution. Only succes stories here…
I entered the following;
sudo systemctl enable myprog.service: nothing special
sudo systemctl start myprog.service: service is not loaded properly…
sudo systemctl status myprog.service: error (invalid argument), inactive (dead).

Both from bash or within QTerminal: behaviour is the same.

Please help me out what to do.
Kind regards,
Harke

Hello,

Look here: https://www.freedesktop.org/software/systemd/man/systemd.service.html#Examples. I think you may need to rummage around in that site to look up your particular need but I am sure you can find what you are looking to gain on that site.

Seth

P.S. If you are having complications still, please reply. I will look up some items on your reply transmission. Okay! I hope to hear from you soon.

Hello Again Harke,

Seth here. You need to put your .service files in /etc/systemd/system/. I am pretty sure.

Seth

Hello Seth,

Thanks a lot for your reaction. I already digested these pages (as good as I could, I am an RF engineer, not a programmer). Unfortunately this does not help me much. The service file is at the correct location.
I hope to get some clue where I am doing something wrong.
Thanks again, regards,
Harke

Hello,

When you type under [Service], use only the PATH. Try that idea first. I may be able to help out a bit.

Seth

P.S. For instance, say I have a Python file in this dir: /home/debian/LoveBone/. I would simply put, under the [Service] tag, ExecStart=/home/debain/LoveBone/MultipleIdeas.py for my PATH. Try that idea and think about moving that [Unit] option for Requires=graphical.target. Try that section under your [Install] section.

Hi Seth,

In the meantime I think I tried just about any combination I can think of.
Mostly I get the following error codes after demanding the status;
Loaded…
Active: failed
Process: 1002 … code = exited, status=203/EXEC
Main PID: 1002…

In short; no luck so far…
I am doing something fundamentally wrong I think… Or it is just impossible.
I am lost here…
Cheers,
Harke

Hello Harke,

Seth here. Um, are you trying to run a specific piece of software only or are you trying to run multiple pieces of software?

Seth

P.S. I know you have to make a file accessible at /etc/systemd/system/<your .service file here> w/ the proper instructions in that .service file. Now, to make it run should be easy, i.e. if this is just one piece of software.

[Unit]
Description=More of what will happen!

[Service]
ExecStart= /your/path/to/the/.py/file.py

[Install]
WantedBy=multi-user.target

^

Try this!

Thank you for your support Seth! I do not think I am running anything special. Just one Python script, 400 lines of my code, many thousends in libs, I guess. From QTerminal command line it runs perfectly. From within a service not.
Looking at your proposal: do you really intend to write: ExecStart= /path/myprog.py instead of: ExecStart=python /path/myprog.py???
That wonders me.
I “sudo nano” the service file and then write it in the /etc/systemd/system/ folder. Nothing else I do.
Is that sufficient?
Thanks a lot again.
Regards,
Harke

Hi Harke,

I am hoping to build up some good will to get an answer to my question, so let me see if I can pitch in. Plus I wanted to get a systemd service working anyway, which I did successfully this morning. Here are the steps I took.

1) Create the application. I wrote a stupid python program:

#!/bin/env python
import sys
print('It ran once.')
sys.exit(0)

2) Create the service file
- Two ways to do this. First you can create a file in /etc/systemd/system/test.service (or whatever name you like) and edit it manually. Or you can run systemctl edit --force test.service to do the same thing.
- The file shall have 644 permissions, root:root owner.

- Paste the following simple service file

[Unit]
Description=Test

[Service]
ExecStart=/usr/bin/python /home/debian/test.py

[Install]
WantedBy=multi-user.target

3. Enable the service file. Run: systemctl enable test
- Response will be: Created symlink /etc/systemd/system/multi-user.target.wants/test.service → /etc/systemd/system/test.service.

4. Check status. Run: systemctl status test

- Response should be:
● test.service - Test
Loaded: loaded (/etc/systemd/system/test.service; enabled; vendor preset: enabled)
Active: inactive (dead) since Mon 2018-12-03 14:18:33 UTC; 1s ago
Process: 2853 ExecStart=/usr/bin/python /home/debian/test.py (code=exited, status=0/SUCCESS)
Main PID: 2853 (code=exited, status=0/SUCCESS)

Dec 03 14:18:33 beaglebone systemd[1]: Started Test.
Dec 03 14:18:33 beaglebone python[2853]: It ran once.

5. Now that you have something stupid working, change the files and increase level of complexity. Replace my idiotic test.py program with your real one. In editing the service file ensure you use absolute path. Update the test.service script and make sure that you run: systemctl daemon-reload whenever you change the service files.

Hope that helps. It worked for me.

Best,

Jim

Hello jim,

Many thanks for chiming in! I copied your example, only close, and then got an error that I need to provide the complete path for python as well. It never occured to me as I thought I can invoke Python just from about everywhere. No way. Now it loads the proper way. Unfortunately my application still does not start correctly: after importing several other libraries (like Adafruit) the import of serial (pyserial) goes wrong and the service halts. I have no idea what goes wrong this time. When I invoke python from the command line in QTerminal the application starts correctly, so included the import of serial and other libraries…
Is this a python issue or what?
Maybe time for another topic?
Anyway: Seth and Jim thanks again for your time and effort. Well appreciated!
Best regards.
Harke

Harke,

Did you, in the software example you created, add #!/usr/bin/python3 to the top of your program and then use this command: sudo chmod a+x YourFile.py? Now, you should be able to run your .service file like before from the example I had given.

Seth

Looks like we are close. But the error codes are persistent. I can not copy/paste but serial does not load. Whatever I place in the first line of the python file.
I tried: #!/bin/env/python and other shebangs (I learn!) but the error remains exactly the same. Btw: I use python2.x
Any clue what to try next please?
Cheers,
Harke

Hello,

If you are using an environment, env, to run your software on boot, I may be out of line. I do not use environments for my Linux Distros when running software on boot. Um, I think if you just type up your software w/ Python2 and add the top line #!/usr/bin/python to the software, you should be able, after using the command sudo chmod a+x YourFile.py, to then run your software on boot under Debian.

Oh…if your env is, let us say, Bien, then just use /home/debian/Bien/YourFile.py under the [Service] section of the .service file. Please remember to have the .service ending to that file, the .service file, in /etc/systemd/system/.

Seth

P.S. Please let me know what happens. If I am not making any sense to you, let me know what does not make sense. I will try to better type out what exactly it is that I learned to make files run on boot w/ .service files.

Okay and Hello Once More,

Seth here. I think (know) Jim F was on to something w/ your software and setting up .service files for running on boot.

For example: Here is another test example to try out to learn more about .service files and starting files on boot on the BBB (or other related bbb.io boards).

`
#!/usr/bin/python

import Adafruit_BBIO.GPIO as GPIO
import time

#your awesome software
`

Now…that example, like w/ what Jim F was typing out, is an example not for your use. You will need to replace all the software w/ your software but do use the first line.

Oh…here is an example of that file above in Python in a .service file w/ the name Pluck.py as the file name. Oh and let us call the .service file Pluck.service.

[Unit]
Description=Some Amount of Understanding for Your File

[Service]
ExecStart=/home/debian/Pluck.py

[Install]
WantedBy=multi-user.target

Now…try to run your .service file that should be saved in /etc/systemd/system/ as Pluck.service.

Then, type this command: sudo systemctl enable Pluck.service

Then, type this command: sudo systemctl start Pluck.service

That should do it!

If not, please reply w/ any relative ideas that are preventing your use of a file on boot, e.g. errors and why the started .service file is not working on boot.

Seth

I actually think what you need to do is something along the following line. I don’t think the shebang line makes a difference (rather, I know this) if you pass the python script directly to the python binary.

ExecStart=/usr/bin/python2.7 /path/to/my_file.py

You should post your errors if Seth's or my comments don't get you on track.

Jim

Hello Jim and Seth,

Thank you for your support. The service test scripts all run fine. My own scripts persist in the error given above. My own service loads but aborts at import serial, which, I guess, has not so much to do with serial, as with something else. I will try and upload the relevant data and errors.
Keep you posted.
Thanks again (it getting very annoying though…), cheers,
Harke

login as: debian
debian@Beaglebone’s password:

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Wed Dec 5 18:01:26 2018 from 2001:982:c7c1:1:a96e:5bfc:cb2a:81a7
debian@beaglebone:~$ sudo systemctl status aceme
[sudo] password for debian:
● aceme.service - to invoke aceme.py automatically
Loaded: loaded (/etc/systemd/system/aceme.service; enabled; vendor preset: enabled)
Active: failed (Result: exit-code) since Wed 2018-12-05 19:39:44 UTC; 3min 50s ago
Process: 986 ExecStart=/home/debian/eme/acemev35.py (code=exited, status=1/FAILURE)
Main PID: 986 (code=exited, status=1/FAILURE)

Dec 05 19:39:40 beaglebone systemd[1]: Started to invoke aceme.py automatically.
Dec 05 19:39:44 beaglebone python[986]: Adafruit_BBIO: version initialized
Dec 05 19:39:44 beaglebone acemev35.py[986]: Traceback (most recent call last):
Dec 05 19:39:44 beaglebone acemev35.py[986]: File “/home/debian/eme/acemev35.py”, line 21, in
Dec 05 19:39:44 beaglebone acemev35.py[986]: import serial # serial control module
Dec 05 19:39:44 beaglebone acemev35.py[986]: ImportError: No module named serial
Dec 05 19:39:44 beaglebone systemd[1]: aceme.service: Main process exited, code=exited, status=1/FAILURE
Dec 05 19:39:44 beaglebone systemd[1]: aceme.service: Unit entered failed state.
Dec 05 19:39:44 beaglebone systemd[1]: aceme.service: Failed with result ‘exit-code’.
debian@beaglebone:~$

here is the status of aceme.service immediately after booting. It is clear that serial is loaded on my system, as I use it extensively in the same program script loaded.

login as: debian
debian@Beaglebone’s password:

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Wed Dec 5 18:01:26 2018 from 2001:982:c7c1:1:a96e:5bfc:cb2a:81a7
debian@beaglebone:~$ sudo systemctl status aceme
[sudo] password for debian:
● aceme.service - to invoke aceme.py automatically
Loaded: loaded (/etc/systemd/system/aceme.service; enabled; vendor preset: enabled)
Active: failed (Result: exit-code) since Wed 2018-12-05 19:39:44 UTC; 3min 50s ago
Process: 986 ExecStart=/home/debian/eme/acemev35.py (code=exited, status=1/FAILURE)
Main PID: 986 (code=exited, status=1/FAILURE)

Dec 05 19:39:40 beaglebone systemd[1]: Started to invoke aceme.py automatically.
Dec 05 19:39:44 beaglebone python[986]: Adafruit_BBIO: version initialized
Dec 05 19:39:44 beaglebone acemev35.py[986]: Traceback (most recent call last):
Dec 05 19:39:44 beaglebone acemev35.py[986]: File “/home/debian/eme/acemev35.py”, line 21, in
Dec 05 19:39:44 beaglebone acemev35.py[986]: import serial # serial control module
Dec 05 19:39:44 beaglebone acemev35.py[986]: ImportError: No module named serial
Dec 05 19:39:44 beaglebone systemd[1]: aceme.service: Main process exited, code=exited, status=1/FAILURE
Dec 05 19:39:44 beaglebone systemd[1]: aceme.service: Unit entered failed state.
Dec 05 19:39:44 beaglebone systemd[1]: aceme.service: Failed with result ‘exit-code’.
debian@beaglebone:~$ sudo nano /etc/systemd/system/aceme.service
GNU nano 2.7.4 File: /etc/systemd/system/aceme.service

[Unit]
Description=to invoke aceme.py automatically
Requires=graphical.target

[Service]
Type=simple
ExecStart=/home/debian/eme/acemev35.py

[Install]
WantedBy=multi-user.target

[ Read 11 lines ]
The service file above…

Grtz,
Harke

Harke,

You should try running your script from the cli using the exact same command you use for the exec start line in your service file. It should give you the same errors you are seeing. That would be good. If not, the problem is that your environment doesn’t match. It will probably end up being your PYTHONPATH. In that case you may want to write a short bash script which sets the path and runs your python script, and using that for your exec start command.

Fundamentally your python doesn’t know where the libraries you want are installed. PYTHONPATH is the environment variable which tends python where to look. Copy the one from your environment and export it in your bash script.

Jim

Hi Jim,

No problem, I can do that, in fact I have done that many times with the same results. I can enter: cd /home/debian/eme/ and then: python aceme.py or I can enter: python /home/debian/eme/aceme.py. That works in both ways exactly the same. When run under the bash it gives an error saying that Tkinter does not work because of a $Display error. When run under QTerminal in LXQT it works fine. This is the reason that I must be sure in the service file that the graphics modules are loaded first. In fact this is the (only) way to start the application.
Conclusion: the command line: python /home/debian/eme/aceme.py works perfectly. However, this is not what I need to put after: ExecStart (as far as I understand…). Now I have: ExecStart=/home/debian/eme/aceme.py. And I made aceme.py executable.
I do not know bash scripts so if necessary please help me here.
I hope this helps in the analysis.
Best regards,
Harke

I was actually thinking you should make sure you run the exact same python. So if your exec start line says /usr/bin/python2.7 aceme.py then you should run that. Then pay attention to the comments about the pythonpath in my previous email.

But your other descriptions are not promising. I don’t think you should be using a systemd service to start an interactive application with a display. Usually systemd services are headless. Perhaps I am mistaken there. It certainly is not typically used that way.

Jim