如何在unix系统中用别的用户运行一个程序?
1、问题的缘由
实际开发系统的时候,经常需要用别的用户运行一个程序。比如,有些系统为保证系统安全,不允许使用root来运行。这里,我们总结了unix系统下如何解决这个问题的一些方法。同时,我们还讨论如何在python脚本里实现。
2、unix系统的方法
2.1、runuser
runuser允许使用替代用户和组ID来运行命令。如果选项-u没有给出,则回退到su兼容的语义和shell被执行。
- runuser和su命令之间的区别在于runuser不要求输入密码(因为它可能仅由root用户执行),它使用不同的PAM配置。命令runuser不必与suid权限一起安装。
 - 当没有参数调用时,runuser默认以root用户身份运行交互式shell。
 - 为了向后兼容,runuser默认不更改当前目录并仅设置环境变量HOME和SHELL(加上USER和LOG- 如果目标用户不是root用户,则为NAME)。此版本的runuser使用PAM进行会话管理
 
用法:
runuser [options] -u <USER> COMMAND
runuser [options] [-] [USER [arg]...]
案例:
runuser -l elastic -c "ls /var/opt/elastic"
如果当前用户不是root:
runuser: may not be used by non-root users
2.2、su
su允许使用替代用户和组ID来运行命令。
- 当没有参数的情况下调用su时默认以root身份运行交互式shell。
 - 为了向后兼容,su默认不更改当前目录并仅设置环境变量HOME和SHELL(如果目标用户不是root的话,加上USER和LOGNAME)。
 - 建议始终使用--login选项(而不是快捷方式-),以避免混合环境导致的副作用,
 - su使用PAM进行认证,帐户和会话管理。在其他su实现中有一些配置选项,例如 必须通过PAM配置wheel组的支持。
 
案例:
$ su -l elastic
Password:*****
$ whoami
elastic
2.3、sudo
sudo允许允许的用户按照安全策略的规定,以超级用户或其他用户的身份执行命令。
- sudo支持安全策略和输入/输出日志记录的插件体系结构。第三方可以开发和分发自己的策略和I / O日志插件与sudo前端无缝协作。
 - 默认安全策略是sudoers,通过/ etc / sudoers文件或通过LDAP配置。看PLUGINS部分获取更多信息。
 - 安全策略确定用户必须运行sudo的权限(如果有的话)。该政策可能要求用户使用密码或另一种认证机制验证自己身份。如果需要验证,如果用户的密码未在可配置的时间限制内输入,则sudo将退出。sudoers安全策略的默认密码提示超时为5分钟。安全策略可以支持凭证缓存,以允许用户在不需要认证的情况下再次运行sudo一段时间。 sudoers 安全策略的缓存凭证5分钟,除非在sudoers(5)中覆盖。通过使用-v选项运行sudo,用户无需更新缓存的凭据
运行一个命令。当作为sudoedit被调用时,隐含-e选项。安全策略可能会记录成功和失败的尝试使用sudo。如果配置了I / O插件,则记录运行命令的输入和输出。 
案例:
sudo -u jim -g audio vi ~jim/sound.txt
2.4、总结
| 
 命令  | 
 root到用户  | 
 用户到root  | 
 任何用户间  | 
 身份验证  | 
 系统支持  | 
 日志  | 
 解释  | 
|---|---|---|---|---|---|---|---|
| 
 runuser  | 
 Y  | 
 N  | 
 N  | 
 不需要  | 
 Linux:是 Solaris:不 MacOS:是  | 
 N/A  | 
 不用身份验证,效率较高  | 
| 
 su  | 
 Y  | 
 Y  | 
 Y  | 
 目标用户的密码  | 
 Linux:是 Solaris:是 MacOS:是  | 
 /var/log/auth.log 或 /var/log/secure  | 
 必须提供用户密码  | 
| 
 sudo  | 
 Y  | 
 Y  | 
 Y  | 
 用户需要验证本人身份  | 
 Linux:是 Solaris:不 MacOS:是  | 
 /var/log/auth.log 或 /var/log/secure  | 
 用户必须是wheel组的成员,可以执行管理员的工作  | 
3、python脚本的方法
在实际工作中,越来越多需要用python来自动化任务、集成不同的部件、处理数据。很多时候会碰到同样问题:如何在python脚本中调用不同用户来运行程序。
- 定义一个函数来设置正在运行的进程的gid和uid。
 - 将此函数作为preexec_fn参数传递给subprocess.Popen
 
subprocess.Popen将使用fork / exec模型来使用preexec_fn。这等同于按顺序调用
- os.fork(),
 - preexec_fn()(在子进程中),
 - os.exec()(在子进程中)
 
必须注意,由于os.setuid,os.setgid和preexec_fn仅在Unix上受支持,因此此解决方案仅支持unix及相关系统。
import os, pwd, subprocess, sys # set gid and uid
def demote(user_uid, user_gid):
def result():
os.setgid(user_gid)
os.setuid(user_uid)
return result # run a command under a new user
def run_command(cmd, user_name, cwd):
pw_record = pwd.getpwnam(user_name)
user_name = pw_record.pw_name
user_uid = pw_record.pw_uid
user_gid = pw_record.pw_gid # get env variable
env = os.environ.copy()
env[ 'HOME' ] = pw_record.pw_dir
env[ 'LOGNAME' ] = user_name
env[ 'PWD' ] = cwd
env[ 'USER' ] = user_name
proc = subprocess.Popen(cmd,
preexec_fn=demote(user_uid, user_gid),
cwd=cwd, env=env )
return proc.communicate()
如何在unix系统中用别的用户运行一个程序?的更多相关文章
- 如何让Windows程序只运行一个程序实例?
		
要实现VC++或者MFC只运行一个程序实例,一般采用互斥量来实现,即首先用互斥量封装一个只运行一个程序实例的函数接口: HANDLE hMutex = NULL; void MainDlg::RunS ...
 - linux下在root用户登陆状态下,以指定用户运行脚本程序实现方式
		
aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMcAAABKCAIAAACASdeXAAAEoUlEQVR4nO2dy7WlIBBFTYIoSIIkmD ...
 - 如何在linux下安装jdk并运行java程序
		
一.进入root 大家可以看到我这里用的是CentOS 6.5 系统 二.测试网络与YUM是否可用 1.测试网络 ping www.baidu.com,如下图就是通了 参考: 一.JDK安装1.lin ...
 - Unix系统编程()进程和程序
		
进程(process)是一个可执行程序(program)的实例. 程序是包含了一系列信息的文件,这些信息描述了如何在运行时创建一个进程,所包括的内容如下所示. 二进制格式标识:每个程序文件都包含用于描 ...
 - C#:只运行一个程序
		
一.通过系统事件 1.实现如下: using System; using System.Collections.Generic; using System.Linq; using System.Tex ...
 - VC只运行一个程序实例
		
方法有很多,以下只是提供一种用的多的 一. 单文档程序 在程序App类的InitInstance中添加如下代码 BOOL CDDZApp::InitInstance() { /*只运行一个实例*/ / ...
 - Winform程序只允许运行一个程序实例
		
/// <summary> /// 应用程序的主入口点. /// </summary> [STAThread] static void Main() { Application ...
 - 在VMware装了linux系统,如何在windows系统中用xshell连接
		
网上有好几种方法,不过我觉得这种比较简单 1.找到VMware菜单 打开 编辑>虚拟网络编辑器 如图: 点下面的更改设置 点确定就可以了,什么都不用改.然后回到linux系统中ifconfig ...
 - Root用户让其他用户运行某程序
		
这里以启动tomcat为例 1.安装tomcat不介绍了,自己百度 2.测试能否使用,略 3.创建tomcat用户 useradd tomcat -s /sbin/nologin 创建tomcat,禁 ...
 
随机推荐
- Joinpoint继承体系-笔记
			
Joinpoint继承层次图: 由上图可以知道的所有的接口的实现都在ReflectiveMethodInvocation这个类中.ConstructorInvocation接口只有一个方法,这个方法的 ...
 - sql排序方法
			
SQL Server中使用order by charindex按指定顺序排序 在使用SQL Server数据库编程中,有时需要对取出来的数据按照指定的顺序排序,例如,取出来的数据某个字段值有张三.李四 ...
 - ganache-cli
			
安装: npm install -g ganache-cli@6.1.8 使用: userdeMacBook-Pro:~ user$ ganache-cli -m "success rifl ...
 - springboot不使用内置tomcat启动,用jetty或undertow
			
Spring Boot启动程序通常使用Tomcat作为默认的嵌入式服务器.如果需要更改 - 您可以排除Tomcat依赖项并改为包含Jetty或Undertow: jetty配置: <depend ...
 - PATtest1.3:最大子列和
			
题目源于:https://pintia.cn/problem-sets/16/problems/663 题目要求:输入一个数列,求其最大子列和. 问题反馈:1.部分C++代码不是很熟练 2.没有仔细读 ...
 - P1719 最大加权矩形
			
题目描述 为了更好的备战NOIP2013,电脑组的几个女孩子LYQ,ZSC,ZHQ认为,我们不光需要机房,我们还需要运动,于是就决定找校长申请一块电脑组的课余运动场地,听说她们都是电脑组的高手,校长没 ...
 - K2 BPM介绍(1)
			
K2 BPM介绍(1) 官网访问地址: 中文官网 英文官网 它是一个强大的BPM产品 K2 BPM详解 产品特性 与任何内容集成 Integrate with Anything 功能丰富的窗体 Fea ...
 - 控制层方法中获取url目录
			
控制层方法中获取url目录 Request.Url.GetLeftPart(UriPartial.Authority).ToString(); //返回 http://localhost:9246(网 ...
 - 聊聊并发——深入分析ConcurrentHashMap
			
术语定义 术语 英文 解释 哈希算法 hash algorithm 是一种将任意内容的输入转换成相同长度输出的加密方式,其输出被称为哈希值. 哈希表 hash table 根据设定的哈希函数H(key ...
 - ios宏定义学习
			
宏简介: 宏是一种批量处理的称谓.一般说来,宏是一种规则或模式,或称语法替换 ,用于说明某一特定输入(通常是字符串)如何根据预定义的规则转换成对应的输出(通常也是字符串).这种替换在预编译时进行,称作 ...