我正在尝试以python 3.6
中与popen
不同的用户身份在subprocess
中执行命令,但该命令仍将以调用脚本的用户身份执行(我计划调用该脚本)作为根)。我正在使用线程,因此在2个线程并行执行时不要侵犯用户权限很重要。
proc = subprocess.Popen(['echo $USER; touch myFile.txt'],
shell=True,
env={'FOO':'bar', 'USER':'www-data'},
stdout=subprocess.PIPE)
上面的示例仍将使用我的myFile.txt
创建user_id 1000
我尝试了不同的方法:
通过复制os.environment尝试Run child processes as different user from a long running Python process中所述,并更改了用户等。
(请注意,这是针对python 2的)
使用start_new_session=True
我的最后一个选择是在命令前加上sudo -u username command
,但我认为这不是一种优雅的方法。
答案 0 :(得分:1)
[仅适用于POSIX]的标准方法是使用preexec_fn
来设置gid和uid,如this answer
类似的事情应该可以解决问题-为了完整起见,我还修改了您的初始代码段以包含您可能想要设置的其他环境变量,但是简单地设置preexec_fn
就足够了您正在运行的命令:
import os, pwd, subprocess
def demote(user_uid, user_gid):
def result():
os.setgid(user_gid)
os.setuid(user_uid)
return result
def exec_cmd(username):
# get user info from username
pw_record = pwd.getpwnam(username)
homedir = pw_record.pw_dir
user_uid = pw_record.pw_uid
user_gid = pw_record.pw_gid
env = os.environ.copy()
env.update({'HOME': homedir, 'LOGNAME': username, 'PWD': os.getcwd(), 'FOO': 'bar', 'USER': username})
# execute the command
proc = subprocess.Popen(['echo $USER; touch myFile.txt'],
shell=True,
env=env,
preexec_fn=demote(user_uid, user_gid),
stdout=subprocess.PIPE)
proc.wait()
exec_cmd('www-data')
请注意,您还需要确保降级的用户可以访问(例如,用于写入)当前工作目录,因为它不会明确覆盖它