如何复制文件并保留原始权限?

huangapple go评论109阅读模式
英文:

How do I copy a file retaining the original permissions?

问题

我想使用纯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语言中是否有可能实现这个功能?

英文:

I would like to copy a file using pure Go, emulating the behavior of cp -p.

My copy function currently looks like:

// 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()
}

which will create dst owned by whoever is running the process. Instead, I would like to keep the owner and permissions of src, i.e. what I get from:

// 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()
}

but without having to call through to system commands (for portability). Everything I tried ended up calling through to something else. Is this possible to do in Go?

答案1

得分: 4

在Go语言中,确实可以实现这个功能,但不能以一种与系统无关的方式(因为不同的操作系统内核对于“权限”的概念和实现方式有所不同)。

此外,还需要考虑复制文件的进程使用的身份可能没有足够的权限来设置目标文件的权限(例如,在Linux上,非root用户无法将文件的所属组更改为用户不是成员的组,显然也无法将文件所有者设置为其他人,换句话说,普通用户无法转移所有权,只能在其自己定义的“圈子”中与其他用户共享文件,这个“圈子”由组成员身份定义)。

基本上,要实现你想要的功能,你需要在创建目标文件后,使用Stat函数获取源文件的信息,然后使用os.Chmod函数(如果需要,还可以使用os.Chown函数)设置目标文件的权限。

此外,请注意,Linux本地文件系统支持文件的POSIX ACLs,每个文件可能有也可能没有这些ACLs。关于是否将其包含在你所定义的“权限”中,这是一个开放的问题。

英文:

It's definitely possible in Go but not in a system-independent manner (because different OS kernels have different ideas about what "permissions" are, and how they are implemented).

Also consider that the identity used by the process copying the file might have insufficient permissions to set permissions on the target file (for instance, on Linux, a non-root user cannot change the owning group of a file to a group the user is not a member of, and it obviously cannot set the file owner to anyone other than theirselves — in other words, mere mortals cannot transfer ownerwhip, only share files within their own "circles" defined by group membership).

Basically, to do what you'r after, you have to Stat the source file and then os.Chmod (and os.Chown, if needed) the destination file after it is created.


Also please note that Linux-native filesystems support POSIX ACLs on files, and each file might or might not have them.
Whether you include this in what you define "permissions" are, is an open question.

huangapple
  • 本文由 发表于 2021年12月10日 19:44:55
  • 转载请务必保留本文链接:https://go.coder-hub.com/70304022.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定