使用sudo在python中创建文件会使其所有者为root

9
我有一个简单的 Python 脚本叫做 myCreate.py,在 Linux 上运行:
fo = open("./testFile.txt", "wb") 当我运行 python ./myCreate.py 时,testFile.txt 的所有者是我的用户。 当我运行 sudo python ./myCreate.py 时,testFile.txt 的所有者变成了 root。
在这两次执行之前,testFile.txt 并没有运行过。
如何让文件所有者保持真实用户而不是有效用户呢?谢谢!

创建它后,请使用“chown”更改其所有者。 - Jim Garrison
我希望它以真实用户的身份打开,而不管这个用户是谁... 不要硬编码。 - iddqd
您可以确定当前用户并将其更改为该用户。 - Jim Garrison
1
root 是您的进程的真实用户ID。非 root 身份是某个父(或祖父)进程的真实用户ID。 - Robᵩ
3
根据sudo man页面的介绍,“当sudo执行一个命令时...通常情况下,真实和有效的用户ID以及组ID将被设置为目标用户所匹配的ID。” - Robᵩ
显示剩余4条评论
3个回答

9

使用sudo运行脚本意味着您以root身份运行它。因此,文件属于root是正常的。

您可以在创建文件后更改文件的所有权。为了做到这一点,您需要知道哪个用户运行sudo。幸运的是,有一个SUDO_UID环境变量在使用sudo时设置。

所以,您可以执行以下操作:

import os
print(os.environ.get('SUDO_UID'))

然后,您需要更改文件所有权
os.chown("path/to/file", uid, gid)

如果我们把它放在一起:
import os

uid = int(os.environ.get('SUDO_UID'))
gid = int(os.environ.get('SUDO_GID'))

os.chown("path/to/file", uid, gid)

当然,你希望将其作为一个函数,因为这样更加方便,所以:

import os

def fix_ownership(path):
    """Change the owner of the file to SUDO_UID"""

    uid = os.environ.get('SUDO_UID')
    gid = os.environ.get('SUDO_GID')
    if uid is not None:
        os.chown(path, int(uid), int(gid))

def get_file(path, mode="a+"):
    """Create a file if it does not exists, fix ownership and return it open"""

    # first, create the file and close it immediatly
    open(path, 'a').close()

    # then fix the ownership
    fix_ownership(path)

    # open the file and return it
    return open(path, mode)

使用方法:

# If you just want to fix the ownership of a file without opening it
fix_ownership("myfile.txt")

# if you want to create a file with the correct rights
myfile = get_file(path)

编辑:由于@Basilevs、@Robᵩ和@5gon12eder的帮助,我更新了我的答案。


@Robᵩ,你是对的,我已经用SUDO_UID更新了我的答案。Basilevs,它解决了编码问题吗?5gon12eder,啊,谢谢你指出这个问题,我已经编辑了我的答案。 - Agate
假设您在get_file方法中使用了open(path, 'a').close()这行代码来创建一个新文件,那么您不想使用'a+'吗? - user3960432
@EliotBerriot 嗯,我们在这里已经无能为力了 :) - Basilevs
@iChar,你说得对,我会相应地编辑我的答案。谢谢。 - Agate
这仅涵盖用户直接从sudo而不是_root_进入的情况。即,如果用户是root(例如通过sudo su),则此方法将无效。@cbrendanprice的答案更为正确。 - Granitosaurus
显示剩余2条评论

2

可以尝试使用os.stat先获取包含文件的文件夹的权限,然后在创建文件时应用这些权限。

具体操作如下(使用Python2):

import os

path = os.getcwd()
statinfo = os.stat(path)

fo = open("./testFile.txt", "wb")
fo.close()
euid = os.geteuid()
if (euid == 0) # Check if ran as root, and set appropriate permissioning afterwards to avoid root ownership
    os.chown('./testFile.txt', statinfo.st_uid, statinfo.st_gid)

正如Elliot所指出的,如果您要同时创建多个文件,最好将其结构化为一个函数。

2

使用os.environ查找适当的用户id,然后使用os.chown()函数:

import os

fo = open("./testFile.txt", "wb")
fo.close()
os.chown('./testFile.txt',
         int(os.environ['SUDO_UID']),
         int(os.environ['SUDO_GID']))

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