【问题标题】:How do I copy a file retaining the original permissions?如何复制保留原始权限的文件?
【发布时间】:2022-01-15 02:48:40
【问题描述】:

我想使用纯 Go 复制文件,模仿 cp -p 的行为。

我的copy 函数目前看起来像:

// copy creates a copy of the file located at `dst` at `src`.
func copyFile(src, dst string) error {
    in, err := os.Open(src)
    if err != nil {
        return err
    }
    defer in.Close()

    out, err := os.Create(dst)
    if err != nil {
        return err
    }

    _, err = io.Copy(out, in)
    if err != nil {
        out.Close()
        return err
    }
    return out.Close()
}

这将创建由运行该进程的任何人拥有的dst。相反,我想保留src 的所有者和权限,即我从中得到什么:

// copy creates a copy of the file located at `dst` at `src`.
func copyFile(src, dst string) error {
    cmd := exec.Command("cp", "-p", src, dst)
    return cmd.Run()
}

但不必调用系统命令(为了便携性)。我尝试的一切最终都通过其他方式调用。这可以在 Go 中实现吗?

【问题讨论】:

    标签: linux file go


    【解决方案1】:

    这在 Go 中绝对是可能的,但不是以独立于系统的方式(因为不同的操作系统内核对什么是“权限”以及如何实现它们有不同的想法)。

    还要考虑复制文件的进程使用的身份可能没有足够的权限来设置目标文件的权限(例如,在 Linux 上,非 root 用户无法将文件的所属组更改为用户不是其中的成员,而且它显然不能将文件所有者设置为除自己以外的任何人——换句话说,普通人不能转让 ownerwhip,只能在他们自己的“圈子”内共享文件(由组成员资格定义)。

    基本上,要做你想做的事,你必须Stat源文件,然后os.Chmod(和os.Chown,如果需要)创建后的目标文件。


    另外请注意,Linux 原生文件系统支持文件上的POSIX ACLs,每个文件可能有也可能没有。
    您是否将其包含在您定义的“权限”中,这是一个悬而未决的问题。

    【讨论】:

    • 如果文件是符号链接并且需要提取目标文件的所有权/权限位,也可能需要os.Readlink
    猜你喜欢
    • 2017-04-24
    • 2012-04-17
    • 2012-02-28
    • 2018-05-08
    • 1970-01-01
    • 2013-11-16
    • 1970-01-01
    • 2016-07-08
    • 2013-02-22
    相关资源
    最近更新 更多