python子进程popen以不同用户身份执行

标签 python python-3.x subprocess

我正在尝试在 python 3.6 中以不同的用户身份使用 subprocess 中的 popen 执行命令,但它仍将以用户身份执行谁调用了脚本(我打算以 root 身份调用它)。我正在使用线程,因此当 2 个线程并行执行时不侵犯用户权限很重要。

proc = subprocess.Popen(['echo $USER; touch myFile.txt'],
                          shell=True,
                          env={'FOO':'bar', 'USER':'www-data'},
                          stdout=subprocess.PIPE)

上面的例子仍然会用我的 user_id 1000 创建 myFile.txt

我尝试了不同的方法:

  1. 按照 Run child processes as different user from a long running Python process 中的描述进行了尝试通过复制 os.environment 并更改用户等
    (注意这是针对 python 2 的)

  2. 按照 https://docs.python.org/3.6/library/subprocess.html#popen-constructor 中的描述进行了尝试通过使用 start_new_session=True

我最后的选择是在命令前加上 sudo -u username command 但我认为这不是优雅的方式。

最佳答案

[仅适用于 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')

请注意,您还需要确保降级用户可以访问当前工作目录(例如,用于写入),因为不会显式覆盖它

关于python子进程popen以不同用户身份执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61302291/

相关文章:

Python:读取子进程的标准输出而不打印到文件

python : How to adjust row height of table in docx

python - 如何从 PyPi 包中提取依赖项

python - 在 Tkinter 中创建简单小部件时出现未知语法错误

python - 为什么使用子进程时会出现 FileNotFoundError?

java - 从 Python 与 Jython/Java 通信(子进程)

python - 在 Python 中,如何为 arangodb 创建边缘集合和文档?

python - 如何分配和管理优先级机制

python - 1 liner 'pythonic' 返回集合而不是列表的代码

python - 使用 beautifulsoup 从维基百科表中获取列