英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论