7

I'd like to start xcape with a nice value of -20 as non-root. However setting a nice value of -20 requires root permissions. So I was wondering whether this is somehow possible. I also tried to create a system service and setting User=myuser, but xcape requires xorg and thus DISPLAY and XAUTHORITY

What I got so far:

[Unit]
Description=xcape: esc on caps lock
PartOf=graphical-session.target

[Service]
Type=simple
Nice=-20
ExecStart=/usr/bin/xcape -t 180 -e 'Caps_Lock=Escape'

[Install]
WantedBy=default.target
Liblor
  • 211
  • 2
  • 7

1 Answers1

4

I eventually came up with a workaround using sudo1 as systemd doesn't support this out of the box afaik.

1) Add command to sudoers file

First add the following line to the end of /etc/sudoers (replace myusername with your username, mycommand with the command to execute and adjust the niceness value as you like):

myusername ALL=(root) NOPASSWD: /usr/bin/nice -n -20 sudo -u myusername mycommand

Explanation:
Allow the user myusername to execute the command sudo /usr/bin/nice -n -20 sudo -u myusername mycommand as root without entering a password. Since sudo nice -n -20 mycommand would execute mycommand as root we prepend sudo -u myusername to the command, that way mycommand is executed by myusername. This is a security measure to adhere the principle of least privilege.

2) Execute the command using sudo in the service script

Now we can execute this specific command without entering a password:

[Service]
ExecStart=sudo /usr/bin/nice -n -20 sudo -u myusername mycommand

Example: xcape

/etc/sudoers

myusername ALL=(root) NOPASSWD: /usr/bin/nice -n -20 sudo -u myusername xcape -t 180 -e Caps_Lock=Escape

~/.config/systemd/user/xcape.service

[Unit]
Description=xcape: esc on caps lock
PartOf=graphical-session.target

[Service]
Type=forking
ExecStart=sudo /usr/bin/nice -n -20 sudo -u myusername mycommand

[Install]
WantedBy=default.target

Start the service: systemdctl --user start xcape


1 One could also write a helper executable and use the setuid bit, if sudo is not available.
Liblor
  • 211
  • 2
  • 7