systemd - how to access current user name from system service?
Asked Answered
I

2

6

I want to create system service, which (for each user) will be started just after user login and do some job inside user's $HOME with root privelegies.

Here is sample service:

[Unit]
Description= My User service
After=dbus.service

[Service]
StandardError=journal
ExecStart=/bin/sh -c "cp -r $HOME/.config /root/backup/$USER/$(date)/"  #<- just a sample root task

[Install]
WantedBy=default.target

But $HOME or $USER variables are unavailable. How to access them?

Internship answered 9/6, 2020 at 13:0 Comment(7)
You can specify the directives User= and Group= in the [Service] section of the unit file.Asher
But how can it help?Internship
Have you tried ? Did you have $HOME and $USER ?Asher
for system(without --user) service $USER is always root unless it not set statically in User=Internship
You meant you have tried User=, but $USER is still not available ?Asher
I don't tried User= because I don't have it, because I need to retrieve it in runtime.Internship
I thought you want to run as a normal user, not as root.Asher
G
6

You can use unit specifiers to accomplish this:

%h represents the home folder of the user

%u gets the name of the user

[Unit]
Description= My User service
After=dbus.service

[Service]
StandardError=journal
ExecStart=/bin/sh -c "cp -r %h/.config /root/backup/%u/$(date)/"  #<- just a sample root task

[Install]
WantedBy=default.target
Glossa answered 7/10, 2020 at 17:3 Comment(0)
H
1

To the best of my knowledge, there is no way to access actual user environment variables from a 'system' unit the way you're envisioning.

The approach I would probably use for the example you gave is to have a 'system' path unit that starts at boot and watches for a .needsbackup file in each user's home dir, extracts the username from the path, and in turn triggers your 'system' backup service unit — probably using a template unit so each run of the backup service would get its own instance, eg backup@<user>.service. This makes it easy to pass the username to your backup command, and allows you to see from a glance at your list of running units what user(s) have a backup job running at any given moment. Delete the .needsbackup file before starting the backup command for obvious reasons, and if you want the backup to run every time the user logs in, you can add touch ~/.needsbackup to their .profile (or /etc/profile to make it apply to all users).

I believe there is a more technically correct, elegant way to detect user login directly by having your system service unit hook into the logind D-BUS API, but I can't offer any help there, as I'm really not familiar with those components.

Also note that your question asks about a 'system' service, but your example service file is a 'user' service file. In particular, default.target is only useful in user units. For your 'system' unit, you probably want either multi-user.target or graphical.target.

Helot answered 6/12, 2020 at 18:20 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.