4

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
2
  • did you manage to set it?
    – brauliobo
    Dec 24 '20 at 12:34
  • I came up with a workaround, I posted it as an answer. I hope this helps you :)
    – Liblor
    Dec 25 '20 at 15:26
1

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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.