如何在Python中查找文件或目录的所有者

47

我需要在Python中找到文件或目录的所有者的函数或方法。

该函数应该如下所示:

>>> find_owner("/home/somedir/somefile")
owner3
7个回答

93

我不是很擅长Python,但我能够轻松地编写出以下代码:

from os import stat
from pwd import getpwuid

def find_owner(filename):
    return getpwuid(stat(filename).st_uid).pw_name

1
请注意,默认情况下 os.stat() 不适用于符号链接。要统计符号链接,您需要传递 follow_symlinks=False 参数。 - gye
这个解决方案只适用于Unix吗? - xjcl

30

这是一个老问题,但对于那些想要使用Python 3的简单解决方案的人来说。

您还可以使用pathlib中的Path来解决此问题,通过调用Pathownergroup方法来实现:

from pathlib import Path

path = Path("/path/to/your/file")
owner = path.owner()
group = path.group()
print(f"{path.name} is owned by {owner}:{group}")

因此,在这种情况下,方法可能如下:

from typing import Union
from pathlib import Path

def find_owner(path: Union[str, Path]) -> str:
    path = Path(path)
    return f"{path.owner()}:{path.group()}"

说:NotImplementedError:此系统不支持Path.owner()。 - Semih
根据 https://bugs.python.org/issue46733,似乎 ownergroup 在 Windows 上“无条件地引发 NotImplementedError,因为 pwd 和 grp 模块在 Windows 上不可用”。我没有 Windows,无法为您提供适当的帮助,但可能这是获取 Windows 信息的方法:http://timgolden.me.uk/python/win32_how_do_i/get-the-owner-of-a-file.html - Gábor

22

你想要使用os.stat()

os.stat(path)
 Perform the equivalent of a stat() system call on the given path. 
 (This function follows symlinks; to stat a symlink use lstat().)

The return value is an object whose attributes correspond to the 
members of the stat structure, namely:

- st_mode - protection bits,
- st_ino - inode number,
- st_dev - device,
- st_nlink - number of hard links,
- st_uid - user id of owner,
- st_gid - group id of owner,
- st_size - size of file, in bytes,
- st_atime - time of most recent access,
- st_mtime - time of most recent content modification,
- st_ctime - platform dependent; time of most recent metadata 
             change on Unix, or the time of creation on Windows)

获取所有者UID的使用示例:

from os import stat
stat(my_filename).st_uid

需要注意的是,stat 返回的是用户ID号码(例如root用户的ID为0),而不是实际的用户名。


9

最近我发现一个问题,需要获取所有者用户和组信息,因此我想分享一下我得出的结果:

import os
from pwd import getpwuid
from grp import getgrgid

def get_file_ownership(filename):
    return (
        getpwuid(os.stat(filename).st_uid).pw_name,
        getgrgid(os.stat(filename).st_gid).gr_name
    )

5

以下是示例代码,展示如何查找文件的所有者:

#!/usr/bin/env python
import os
import pwd
filename = '/etc/passwd'
st = os.stat(filename)
uid = st.st_uid
print(uid)
# output: 0
userinfo = pwd.getpwuid(st.st_uid)
print(userinfo)
# output: pwd.struct_passwd(pw_name='root', pw_passwd='x', pw_uid=0, 
#          pw_gid=0, pw_gecos='root', pw_dir='/root', pw_shell='/bin/bash')
ownername = pwd.getpwuid(st.st_uid).pw_name
print(ownername)
# output: root

3

请查看os.stat。它会给你st_uid,即所有者的用户ID。然后您需要将其转换为名称。要执行此操作,请使用pwd.getpwuid


1
在Windows上,这可以工作,但使用命令行界面。
import os
from subprocess import Popen, PIPE
from collections import namedtuple


def sliceit(iterable, tup):
    return iterable[tup[0]:tup[1]].strip()

def convert_cat(line):
    # Column Align Text indicies from cmd
    # Date time dir filesize owner filename
    Stat = namedtuple('Stat', 'date time directory size owner filename')
    stat_index = Stat(date=(0, 11), 
                      time=(11, 18), 
                      directory=(18, 27), 
                      size=(27, 35), 
                      owner=(35, 59), 
                      filename=(59, -1))

    stat = Stat(date=sliceit(line, stat_index.date),
                      time=sliceit(line, stat_index.time),
                      directory=sliceit(line, stat_index.directory),
                      size=sliceit(line, stat_index.size),
                      owner=sliceit(line, stat_index.owner),
                      filename=sliceit(line, stat_index.filename))
    return stat

def stat(path):
    if not os.path.isdir(path):
        dirname, filename = os.path.split(path)
    else:
        dirname = path
    cmd = ["cmd", "/c", "dir", dirname, "/q"]
    session = Popen(cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE)
    # cp1252 is common on my Norwegian Computer,
    # check encoding from your windows system
    result = session.communicate()[0].decode('cp1252')

    if os.path.isdir(path):
        line = result.splitlines()[5]
        return convert_cat(line)
    else:
        for line in result.splitlines()[5:]:
            if filename in line:
                return convert_cat(line)
        else:
            raise Exception('Could not locate file')

if __name__ == '__main__':
    print(stat('C:\\temp').owner)
    print(stat('C:\\temp\\diff.py'))

完美的复制粘贴 - TAITONIUM

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