1
votes
  • Basic background info:

    I'm trying to run my program on os startup (my current OS is Debian 9 latest stable release) my project is listening to the keyboard using Xlib library and I'm also using Tkinter to pop up some UI windows.

  • this is /etc/system/system/my_project.service

[Unit]
Description=Daemon tool that opens the required environment given a 
certain shortcut key

[Service]
Environment="DISPLAY=:0"
ExecStart=/usr/local/bin/keyboard_listener.py

[Install]
WantedBy=multi-user.target
  • after reboot I run: sudo systemctl status my_project.service and I get the following error

May 08 11:49:43 debian keyboard_listener.py[303]: File "/usr/local/lib/python3.5/dist-packages/Xlib/protocol/display.py", line 90, in init

May 08 11:49:43 debian keyboard_listener.py[303]: self.socket = connect.get_socket(name, protocol, host, displayno)

May 08 11:49:43 debian keyboard_listener.py[303]: File "/usr/local/lib/python3.5/dist-packages/Xlib/support/connect.py", line 87, in get_socket

May 08 11:49:43 debian keyboard_listener.py[303]: return mod.get_socket(dname, protocol, host, dno)

May 08 11:49:43 debian keyboard_listener.py[303]: File "/usr/local/lib/python3.5/dist-packages/Xlib/support/unix_connect.py", line 113, in get_socket

May 08 11:49:43 debian keyboard_listener.py[303]: raise error.DisplayConnectionError(dname, str(val))

May 08 11:49:43 debian keyboard_listener.py[303]: Xlib.error.DisplayConnectionError: Can't connect to display ":0": [Errno 111] Connection refused

May 08 11:49:43 debian systemd[1]: my_project.service: Main process exited, code=exited, status=1/FAILURE

May 08 11:49:43 debian systemd[1]: my_project.service: Unit entered failed state.

May 08 11:49:43 debian systemd[1]: my_project.service: Failed with result 'exit-code'.

how can I solve this issue(Erron 111)? should I add something to my_project.service and how can I make my project to run on startup?

1

1 Answers

2
votes

tl;dr: systemd won't work

In absence of explicit ordering dependencies, systemd processes all units in a transaction simultaneously. That means it does not and will not wait for X server to become available on display :0 before starting your .service unit.

In modern GNU/Linux distributions, X server is not started directly by any systemd unit, so you cannot specify a systemd ordering dependency on X server. Hence systemd is not suitable for whatever you are trying to accomplish, at least not until more fine-grained dependency mechanisms are implemented in systemd.

suggested workarounds

As a workaround, you may try /etc/xdg/autostart, ~/.config/autostart or ~/.xinitrc (whatever is applicable for your X.org setup). These scripts are guaranteed to be run from inside a graphical user session.

If status monitoring is desired, you can combine both methods and start a transient systemd unit with systemd-run(1) or equivalent from inside one of those scripts.