我想以递归方式创建一个目录,并为已创建的文件夹及其父级分配所有者和组。
例如,假设存在/var
,我想创建/var/test1/test2/test3
。
我可以使用os.MkdirAll("/var/test1/test2/test3", 0600)
执行此操作。
但是,我还想将test1
,test2
和test3
' uid
设置为user1
和gid
到user1
。
可以使用os.Chown
进行此操作,但这需要大量手动操作。我需要在创建文件夹链之前构建一个不存在的文件夹树及其父文件,然后在创建后在每个文件夹上使用os.Chown
。
有更简单的方法吗?
答案 0 :(得分:4)
有点像这个ChownR()
type of function,想法是过滤walk,并将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()
,此处不应涉及太多“手工作业”。
答案 1 :(得分:1)
将mkdir进程切换到要为其创建目录的用户。这样做的好处是可以在单个命令中创建具有正确权限和所有权的目录,而不是创建循环或连续运行多个命令。
示例:
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()
}
由于子进程" mkdir"以uid
指定的用户身份运行,文件夹已经拥有正确的所有者。如果你正确使用umask部分,每个目录也将拥有正确的权限。
有一点需要注意:这不是一个非常便携的解决方案。如果您确定您的代码只在特定操作系统上执行,那么使用syscall应该只是您的解决方案。