How to start a systemd service after user login and stop it before user logout

34,117

Solution 1

Use systemd it already includes support for user sessions, in fact you should already depend on it (unwittingly).

Create the service directory

mkdir -p $HOME/.local/share/systemd/user

Create edit a service file (vim, gedit, geany - whatever you want)

vim $HOME/.local/share/systemd/user/my.service

It should roughly look like this, if it's a permanent service.

[Unit]
Description=My very own Service
[Service]
Type=simple
TimeoutStartSec=0
ExecStart=/path/to/start/script arguments
[Install]
WantedBy=default.target

But it sounds like you rather want to trigger it once, then be good with it, so rather use a oneshot configuration like this:

[Service]
Type=oneshot
RemainAfterExit=true
StandardOutput=journal
ExecStart=/path/to/start/script arguments
ExecStop=/path/to/stop/script arguments
[Install]
WantedBy=default.target

This of course assumes that your script is executable, i.e.:

chmod a+x /path/to/start/script
chmod a+x /path/to/stop/script

Else you would need to prepend the path to the respective interpreter:

ExecStart=/bin/bash /path/to/start/script arguments

Now reload systemd (and re-login for the sake of testing)

systemctl --user enable my.service # enables the service
systemctl --user # should display your new unit in the list
journalctl --user should show the log

If you need more information refer to the Arch-Wiki for example. This askubuntu thread has various ideas, including incidentally, mine.

You can extend the behaviour (if you are root) to other users by defining the service globally. In order to do this you would need to create the service file in /usr/share/systemd/user/ not in $HOME/.local/share/systemd/user.

Solution 2

I know this a few year old, but the answer from anx just helped me out. So, I guess it's still relevent. Also, this is more of a comment, but I don't have that privledge so I posting it as an "answer". At any rate...

Running Linux Mint 19, I could not "enable" the service when the script was located in '$HOME/.local/share/systemd/user'. Attempting to do so always resulted in a error. I could, however, start it up just fine from the '$HOME/.local/share/systemd/user' directory. After moving the script into '/usr/share/systemd/user/', systemd allowed me to enable it without issue.

Share:
34,117

Related videos on Youtube

GeorgeKaf
Author by

GeorgeKaf

Updated on September 18, 2022

Comments

  • GeorgeKaf
    GeorgeKaf almost 2 years

    I have a Fedora 23 Machine.

    I have a directory/file synchronizing bash script that synchronizes my local /home directory to a remote directory (in a NAS machine). I run it manually but I would like to create a systemd service and make it more flexible, since other people use my PC with their own user credentials, I 'd like to know when a user is logged in and start my service afterwards.

    Is there something I can do from my service's systemd file or will I have to check that from my code in the script?

    I only need to make sure that I have access to environment variables (like $USER) and to run it as a service.

    My main source of documentation is this link https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/System_Administrators_Guide/sect-Managing_Services_with_systemd-Unit_Files.html

  • Anwar
    Anwar over 6 years
    hi, the answer was good. But it will only work if the service should be started at first login and stopped at last user session.
  • Simon Polak
    Simon Polak about 6 years
    You need the --user flag when enabling the service. "systemctl --user enable my.service"
  • ARNAB
    ARNAB over 3 years
    Alert - there is no way to tell system NOT to process your .config/systemd/user services until after you log in - meaning it doesn't work if your HOME directory is encrypted until you have entered your password to login.