递归创建一个具有特定所有者和组的目录。

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

Recursively create a directory with a certain owner and group

问题

我想递归地创建一个目录,并为创建的文件夹及其父级分配所有者和组。

例如,假设/var已经存在,我想创建/var/test1/test2/test3

我可以使用os.MkdirAll("/var/test1/test2/test3", 0600)来实现这一点。

然而,我还想将test1test2test3uid设置为user1gid设置为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.

huangapple
  • 本文由 发表于 2015年10月16日 09:48:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/33161284.html
匿名

发表评论

匿名网友

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

确定