「Linux」- 以其他用户的身份运行命令

  CREATED BY JENKINSBOT

问题描述

在 Linux 中,有时候我们需要以其他用户身份来运行命令,而不是当前登录用于。像 Nginx 或者其他某些应用程序,可以指定在运行时所属的用户和组,但是有些程序则不支持指定用户和组(因为它们自身不支持)。

本笔记将介绍以其他用户身份来运行特定命令的方法。

方法一、使用 systemd 的单元文件

在.service文件中,使用User=和Group=来指定运行命令的用户的组。如下示例:

[Unit]
Description=xxxxxxx

[Service]
User=www-data
Group=www-data
ExecStart=xxxxxxx

方法二、使用 sudo(8) 命令

可以用 sudo(8) 命令,它的作用本来就是“excute a command as another user”,默认为root用户,可以用-u指定所要使用的用户名。

sudo(8)以另一个用户身份执行命令,但遵循一组规则,这些规则决定了哪些用户可以作为哪些其他用户来执行哪些命令。在/etc/sudo(8)ers文件中进行配置。与su(1)不同的是对用户进行身份验证时,sudo(8)使用调用sudo(8)命令的用户的密码,而不是目标用户的密码。 sudo(8)允许系统管理员授权某些用户(或用户组)以root用户或其他用户身份来运行命令的能力,同时提供命令及其参数的审计跟踪。这允许将特定命令委派给特定主机上的特定用户,而无需在其中共享密码。

假设要以user身份执行prog程序:

#!/bin/sh

sudo -u user prog

方法三、使用 su(1) 命令

还可以使用 su(1) 命令。使用su(1)命令切换到另一个身份,运行Shell,再用新的Shell运行指定程序。命令su(1)只能运行Shell程序,虽然可以把命令写成类似于sudo(8)的样子(比如,su -c user prog),但它的实现原理实际上还是先运行一个Shell,再通过Shell运行其他程序。

假设要以user身份执行prog程序,有两种方法:

先切换到user用户,然后执行prog程序:

#!/bin/bash

su - user
prog arg0 arg1 ...

使用命令su(1)的-c选项指定要执行的命令:

#!/bin/bash

su -user -c "prog arg0 arg1 ..."

这两者方法只是形式上的不同,本质上还是相同的。不管使用哪一个,它都会提示你输入用户的密码。

因此,如果要在Shell脚本中使用su命令:

#!/bin/bash

su - root <<HD
root's password
prog arg0 arg1 ...
HD

注意事项
由于要切换到用户user,所以你需要知道user的密码。这一点不同于sudo(8)。

方法四、使用runuser(1)命令

命令runuser(1)使用替代用户和组ID来运行Shell。该命令仅在以root用户身份运行时才有用(原因参阅手册)。

命令的语法如下:

#!/bin/bash

runuser -l  username -c 'command'
runuser -l  username -c '/path/to/command arg1 arg2'

上述方法的对比

角度一:从root切换到其他用户

上述的方法中都可以从root切换到其他用户运行命令。

角度二:从其他用户切换到root

命令runuser(1)不可以,它只能在root身份下运行。但是,sudo(8)与su(1)可以切换到root身份运行命令。

角度三:非root用户间的互相切换

命令runuser(1)不可以,它只能在root身份下运行。但是,sudo(8)与su(1)可以从非root身份切换到另一个非root身份来运行命令。

角度四:用户认证

命令runuser(1)不需要输入密码,因为它只能从root切换到其他用户身份来运行命令。

命令su(1)需要提供目标用户的密码。

命令sudo(8)需要提供当前用户的密码,而不需要提供目标用户的密码。

角度五:日志文件

命令runuser(1)没有日志文件。命令su(1)的日志位于/var/log/auth.log或/var/log/secure中。而命令sudo(8)的日志也位于/var/log/auth.log或/var/log/secure中。

参考文献

Linux Run Command As Another User
LINUX系统 不切换用户 指定用户的身份运行某一程序
systemd: Start process as specific user
How do I make my systemd service run via specific user and start on boot?
systemd.exec — Execution environment configuration
(1)systemd: Start process as specific user
(1)Is there a single line command to do `su`?