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

9

2

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

GeorgeKaf

Posted 2016-02-09T08:15:19.120

Reputation: 193

Does systemctl --user work on F23? – user1686 – 2016-02-09T08:56:18.973

I guess so, It returns a list and a message 76 loaded units listed. – GeorgeKaf – 2016-02-09T09:27:50.720

Here's another approach which might work for you: http://unix.stackexchange.com/a/109270/111707 Write a small Python script which you launch from .bashrc on login, then it listens for Gnome logout signal and shuts itself down.

– IanB – 2017-03-04T10:38:54.887

@IanB Thank you, I will test it. It never hurts to have something like that around. – GeorgeKaf – 2017-03-14T06:19:19.783

Answers

13

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.

anx

Posted 2016-02-09T08:15:19.120

Reputation: 146

1hi, the answer was good. But it will only work if the service should be started at first login and stopped at last user session. – Anwar – 2018-03-26T14:49:45.933

4You need the --user flag when enabling the service. "systemctl --user enable my.service" – blushrt – 2018-05-12T20:01:00.790