如何在init脚本中以特定用户身份运行命令?

40

我正在编写一个初始化脚本,该脚本应该以不同于root用户的身份执行单个命令。这是我当前的做法:
sudo -u username command

在Ubuntu/Debian上,这通常按预期工作,但在RHEL上,作为 command 执行的脚本会挂起。
是否有其他方法可以以另一个用户身份运行命令?
(请注意,我不能使用lsb init函数,因为它们在RHEL/Centos 5.x上不可用。)


2
请注意,此问题涉及仅由管理员设置的内容(通常是作为某个用户运行的守护进程,以确保安全性)。稍微不同的情况是用户自己设置要在启动时运行的命令,使用他们的用户crontab。请参阅http://askubuntu.com/questions/260845/run-a-command-as-user-at-boot-time-ubuntu-12-04。 - Stéphane Gourichon
6个回答

28
在RHEL系统中,/etc/rc.d/init.d/functions 脚本旨在提供类似于您所需的功能。如果您在init脚本的顶部引用它,那么所有函数都将可用。
为此提供的特定函数是daemon。如果您打算使用它来启动类似守护进程的程序,则简单用法如下:
daemon --user=username command

如果这对你的需求来说太过头了,那么可以使用 runuser(查看完整信息请参阅 man runuser;一些版本可能需要在用户名之前加上-u):

/sbin/runuser username -s /bin/bash -c "command(s) to run as user username"

4
至少在RHEL6上,runuser命令不接受-u参数,我们需按照以下方式运行:runuser username -s /bin/bash -c "command"。其中username是要切换到的用户,"command"是要执行的命令。 - Richlv
1
对于Centos 7,也不能使用-u参数,否则命令会失败。而/sbin/runuser username -s /bin/bash -c "command"可以正常工作。 - Hustlion
1
对于任何遇到“选项--(shell,fast,command,session,session-command,login)和--user是互斥的”错误的人,以下格式适用于我:runuser -u username -- command - J. Titus
谢谢@lagweezle,这似乎对我来说很有效,对于停止daemon的最佳方法是什么? 在我的init.d脚本的停止部分吗? - Eradicatore

18

对于systemd风格的init脚本来说,这非常简单。您只需在[Service]部分中添加User=。

这是我在CentOS 7上使用的qbittorrent-nox init脚本:

[Unit]
Description=qbittorrent torrent server

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

[Install]
WantedBy=multi-user.target

2
systemd可能引起争议,但这确实很方便。我将对我(hashicorp)的vault服务器进程进行此操作。谢谢。 - David
我并不关心Linux开发中的戏剧情节 :) 自从CentOS采用systemd以来,我发现它很容易处理。我再也不会回到之前那个混乱的状态了 :) - LOAS

13

不要使用 sudo,尝试使用

su - username command

根据我的经验,在 RHEL 系统中并不总是有 sudo,但是有su,因为 su 是 coreutils 包的一部分,而 sudo 在 sudo 包中。


7
我尝试过这个方法,但它需要为服务用户设置密码,而我并不打算这样做。然而,使用 sudo -u <username> <command> 不需要密码。请注意,我是使用我的用户账户而非 root 账户运行这些命令的。 - Justin C
如果在/etc/sudoers中设置了requiretty(在Cent 6、7和Fedora 20中是默认设置),则sudo命令将无法正常工作。 - spuder
这里也有同样的问题,无法使用su因为它需要密码。那么最好的方法是什么?似乎没有人有一个合适的答案:( - birgersp
这是在RHEL 6上为我工作的方法。我还使用了-m标志来保留环境变量:su -m username command - bmaupin

12

如果你有start-stop-daemon

start-stop-daemon --start --quiet -u username -g usergroup --exec command ...

3
在RHEL 5中没有此功能。 - ddario
2
@ddario start-stop-daemon 是 Debian 的特有命令。 - Ansgar Wiechers
你可以使用daemon,正如@lagweezle在他/她的答案中指出的那样。顺便说一句,这应该是被接受的答案。 - Alberto de Paola
2
-u/--user 用于检查,您应该添加 -c/--chuid:在启动进程之前切换到此用户名/用户ID。 - Tanky Woo

2

2

我添加了这个答案,因为我不得不查找多个地方来实现我的用例。 我有一个在启动时运行的脚本。此脚本以特定(无密码)用户身份运行进程,并在多个Linux版本上运行。以下是不同版本的选项: (我以Java作为目标进程为例)

1. RHEL / CentOS 6:

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

2. RHEL 7 / SUSE12 / 其他使用systemd的Linux版本:

在您的systemd单元文件中添加:

User=myUser

3. Suse 11:

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接