英文:
Recursively create a directory with a certain owner and group
问题
我想递归地创建一个目录,并为创建的文件夹及其父级分配所有者和组。
例如,假设/var已经存在,我想创建/var/test1/test2/test3。
我可以使用os.MkdirAll("/var/test1/test2/test3", 0600)来实现这一点。
然而,我还想将test1、test2和test3的uid设置为user1,gid设置为user1。
可以使用os.Chown来实现,但这需要大量手动工作。我需要在创建文件夹链之前构建一个不存在的文件夹及其父级的树,然后在创建后对每个文件夹使用os.Chown。
有没有更简单的方法?
英文:
I would like to recursively create a directory and assign an owner and group for the folders and its parents that were created.
For example, assuming /var exists, I want to create /var/test1/test2/test3.
I am able to do this using os.MkdirAll("/var/test1/test2/test3", 0600).
However, I also want to set test1, test2, and test3's uid to user1 and gid to user1.
It's possible to do so using os.Chown, but that requires a lot of manually work. I would need build a tree of the folder and its parents that do not exist before creating the folder chain and then use os.Chown on each folder after creation.
Is there a simpler way?
答案1
得分: 7
有点像这样ChownR()类型的函数,想法是过滤遍历,并且仅对作为参数传递的路径的文件夹应用chown(这里是"/var/test1/test2/test3")。
没有过滤器:
func ChownR(path string, uid, gid int) error {
    return filepath.Walk(path, func(name string, info os.FileInfo, err error) error {
        if err == nil {
            err = os.Chown(name, uid, gid)
        }
        return err
    })
}
换句话说,使用filepath.Walk(),这里不应该有太多的"手动工作"。
英文:
A bit like this ChownR() type of function, the idea would be to filter the walk, and apply the chown only to folders which are part of a path passed in parameter (here "/var/test1/test2/test3)
Without filter:
func ChownR(path string, uid, gid int) error {
	return filepath.Walk(path, func(name string, info os.FileInfo, err error) error {
		if err == nil {
			err = os.Chown(name, uid, gid)
		}
		return err
	})
}
In other words, with filepath.Walk(), there should not be too much "manual work" involved here.
答案2
得分: 0
将mkdir过程切换到您希望为其创建目录的用户。这样做的好处是可以使用单个命令创建具有正确权限和所有权的目录,而不是创建循环或连续运行多个命令。
示例:
import "os/exec"
import "syscall"
func main() {
    // 此处的命令可以使用标志一次性创建所有目录
    cmd := exec.Command('mkdir', '-p', '/var/test1/test2/test3/')
    _ = syscall.Umask(0077) // 为此进程设置umask
    cmd.SysProcAttr = &syscall.SysProcAttr{}
    cmd.SysProcAttr.Credential = &syscall.Credential{Uid: uid, Gid: gid}
    cmd.Run()
}
由于子进程"mkdir"以uid指定的用户身份运行,因此文件夹已经具有正确的所有者。如果正确设置了umask部分,每个目录也将具有正确的权限。
一个注意事项:这不是一个非常可移植的解决方案。只有在您确定代码只会在特定操作系统上执行时,才应使用syscall作为解决方案。
英文:
Switch the mkdir process to the user you wish to create directories for. This has the advantage of creating directories with correct permissions and ownership in a single command instead of creating loops or running multiple commands back to back.
Example:
import "os/exec"
import "syscall"
func main() {
    // The command here can use flags to create all of the dirs at once
    cmd := exec.Command('mkdir', '-p', '/var/test1/test2/test3/')
    _ = syscall.Umask(0077) // Set umask for this process
    cmd.SysProcAttr = &syscall.SysProcAttr{}
    cmd.SysProcAttr.Credential = &syscall.Credential{Uid: uid, Gid: gid}
    cmd.Run()
}
Since the subprocess "mkdir" runs as the user specified by uid, the folders would already have the correct owner. If you get the umask part right, each directory will also have correct permissions.
One caveat: this is not a very portable solution. Using syscall should only be your solution if you are certain your code will only be executing on a specific OS.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论