39

I'm writing an init script which is supposed to execute a single command as a user different than root. This is how I'm doing it currently:
sudo -u username command

This generally works as expected on Ubuntu/Debian, but on RHEL the script which is executed as the command hangs.
Is there another way to run the command as another user?
(Note that I can't use lsb init functions as they're not available on RHEL/Centos 5.x.)

Alberto de Paola
  • 1,160
  • 2
  • 15
  • 29
ddario
  • 1,015
  • 3
  • 12
  • 25
  • 2
    Notice that this question is about something set up exclusively by the administrator (typically, a daemon that runs as some user for security). A slightly different case is users setting up on their own commands to run at boot, with their user crontab. See http://askubuntu.com/questions/260845/run-a-command-as-user-at-boot-time-ubuntu-12-04 – Stéphane Gourichon Jan 31 '15 at 07:39

6 Answers6

28

On RHEL systems, the /etc/rc.d/init.d/functions script is intended to provide similar to what you want. If you source that at the top of your init script, all of it's functions become available.

The specific function provided to help with this is daemon. If you are intending to use it to start a daemon-like program, a simple usage would be:

daemon --user=username command

If that is too heavy-handed for what you need, there is runuser (see man runuser for full info; some versions may need -u prior to the username):

/sbin/runuser username -s /bin/bash -c "command(s) to run as user username"
lagweezle
  • 516
  • 5
  • 12
  • 4
    at least on RHEL6, `runuser` does not accept the `-u` parameter and one would run it just like this: `runuser username -s /bin/bash -c "command"` – Richlv Jul 08 '16 at 18:25
  • 1
    For Centos 7, also should not use `-u` or the command fails. And `/sbin/runuser username -s /bin/bash -c "command"` works. – Hustlion Apr 08 '17 at 03:31
  • 1
    For anyone dealing with the error `options --(shell,fast,command,session,session-command,login) and --user are mutually exclusive`, the following format worked for me: `runuser -u username -- command` – J. Titus Nov 06 '20 at 18:15
  • Thanks @lagweezle, this seems like it will work for me for my starting of the command, what's the best way to stop that daemon? in the stop part of my init.d script? – Eradicatore Apr 07 '21 at 16:14
17

For systemd style init scripts it's really easy. You just add a User= in the [Service] section.

Here is an init script I use for qbittorrent-nox on CentOS 7:

[Unit]
Description=qbittorrent torrent server

[Service]
User=<username>
ExecStart=/usr/bin/qbittorrent-nox
Restart=on-abort

[Install]
WantedBy=multi-user.target
LOAS
  • 7,161
  • 2
  • 28
  • 25
  • 2
    systemd may be controversial but this is certainly a nice convenience. I am going to do this for my (hashicorp) vault server process. thanks. – David Jan 10 '18 at 20:28
  • I don't really keep up with linux dev drama :) I have just found systemd easy to deal with since centos adopted it. I am never going back to the mess that preceded it :) – LOAS Jan 11 '18 at 07:38
13

Instead of sudo, try

su - username command

In my experience, sudo is not always available on RHEL systems, but su is, because su is part of the coreutils package whereas sudo is in the sudo package.

Jeff N
  • 3,249
  • 1
  • 12
  • 4
  • 7
    I tried this, but it requires a password for the service user, which I don't intend to ever set. `sudo -u ` on the other hand, does not. Note that I run these with my user account, not a root account. – Justin C Jul 17 '14 at 19:32
  • sudo wont work if `requiretty` is set in /etc/sudoers (the default in cent 6, 7 and fedora 20). – spuder Oct 10 '14 at 17:21
  • Same problem here, cant user su because it requires a password. So what is the best approach for this? Noone seems to have a proper answer :( – birgersp Nov 01 '14 at 10:44
  • This is what worked for me on RHEL 6. I also used the -m flag to preserve environment variables: `su -m username command` – bmaupin Sep 25 '15 at 16:07
12

If you have start-stop-daemon

start-stop-daemon --start --quiet -u username -g usergroup --exec command ...
crafter
  • 6,246
  • 1
  • 34
  • 46
2

I usually do it the way that you are doing it (i.e. sudo -u username command). But, there is also the 'djb' way to run a daemon with privileges of another user. See: http://thedjbway.b0llix.net/daemontools/uidgid.html

mti2935
  • 11,465
  • 3
  • 29
  • 33
2

Adding this answer as I had to lookup multiple places to achieve my use case. I had a script that runs on startup. This script runs process as a specific (passwordless) user and is running on multiple linux flavors. Here are options on different flavors: (I have taken java as target process for example)

1. RHEL / CentOS 6:

source /etc/rc.d/init.d/functions
daemon --user=myUser $JAVA_HOME/bin/java

2. RHEL 7 / SUSE12 / other linux flavors where systemd is used:

In your systemd unit file add:

User=myUser

3. Suse 11:

/sbin/startproc -u myUser $JAVA_HOME/bin/java

tryingToLearn
  • 10,691
  • 12
  • 80
  • 114