Golang递归修改文件和目录的权限(chmod)

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

Golang chmod files and directories recursively

问题

我正在尝试使用WalkDirChmod来递归更改目录及其文件和子目录的权限。但是它只会更改给定路径的第一个文件或目录,然后停止。有人能找出错误吗?getFileMode函数只是将字符串"755"转换为os.FileMode(0755)并返回它。

func ChmodRec(path string, di fs.DirEntry, err error) error {
	fileMode, err2 := getFileMode(os.Getenv("CHMOD_MODE"))
	if err2 != nil {
		log.Fatal("Could not set file mode for chmodding", path)
		panic(err)
	}

	err2 = os.Chmod(path, fileMode)
	if err2 != nil {
		fmt.Println("Could not chmod", path)
		panic(err)
	}
	fmt.Println("Changing mode of", path)
	return nil
}

func ChmodRecursive(path string, mode string) {
	os.Setenv("CHMOD_MODE", mode)
	err := filepath.WalkDir(path, ChmodRec)
	if err != nil {
		log.Fatal("Could not chmod recursively", path)
		panic(err)
	}
}

func main() {
	path := "bla/test/"
	mode := "755"
	ChmodRecursive(path, mode)
}
英文:

I'm trying to use WalkDir with Chmod to recursively change the permission of a directory and its files and subdirectories. Somehow it does just change the first file or directory of the given path and stops afterwards. Can someone spot the mistake? getFileMode just converts the string "755" in os.FileMode(0755) and returns it.

func ChmodRec(path string, di fs.DirEntry, err error) error {
	fileMode, err2 := getFileMode(os.Getenv("CHMOD_MODE"))
	if err2 != nil {
		log.Fatal("Could not set file mode for chmodding", path)
		panic(err)
	}

	err2 = os.Chmod(path, fileMode)
	if err2 != nil {
		fmt.Println("Could not chmod", path)
		panic(err)
	}
	fmt.Println("Changing mode of", path)
	return nil
}

func ChmodRecursive(path string, mode string) {
	os.Setenv("CHMOD_MODE", mode)
	err := filepath.WalkDir(path, ChmodRec)
	if err != nil {
		log.Fatal("Could not chmod recursively ", path)
		panic(err)
	}
}

func main() {
	path := "bla/test/"
	mode := "755"
	ChmodRecursive(path, mode)
}

答案1

得分: 3

你的代码没有检查ChmodRec函数中的err参数。这是官方文档的一部分:

> WalkDir在两种情况下使用非nil的err参数调用该函数。
>
> 首先,如果根目录的初始fs.Stat失败,WalkDir将使用根目录的路径、nil的d和来自fs.Stat的错误来调用该函数。
>
> 其次,如果目录的ReadDir方法失败,WalkDir将使用目录的路径、描述该目录的fs.DirEntry和来自ReadDir的错误来调用该函数。在这第二种情况下,该函数会两次使用目录的路径进行调用:第一次调用是在尝试读取目录之前,err设置为nil,给函数一个机会返回SkipDir并完全避免ReadDir。第二次调用是在ReadDir失败后报告ReadDir的错误。(如果ReadDir成功,就不会有第二次调用。)

将以下代码添加到函数的开头。它可以给你一些提示:

func ChmodRec(path string, di fs.DirEntry, err error) error {
    if err != nil {
        log.Fatal(err)
    }
}
英文:

Your code does not check err argument in ChmodRec. This is an extract from official documentation:

> WalkDir calls the function with a non-nil err argument in two cases.
>
> First, if the initial fs.Stat on the root directory fails, WalkDir
> calls the function with path set to root, d set to nil, and err set to
> the error from fs.Stat.
>
> Second, if a directory's ReadDir method fails, WalkDir calls the
> function with path set to the directory's path, d set to an
> fs.DirEntry describing the directory, and err set to the error from
> ReadDir. In this second case, the function is called twice with the
> path of the directory: the first call is before the directory read is
> attempted and has err set to nil, giving the function a chance to
> return SkipDir and avoid the ReadDir entirely. The second call is
> after a failed ReadDir and reports the error from ReadDir. (If ReadDir
> succeeds, there is no second call.)

Add this code to the beginning of the function. It can give you a hint:

func ChmodRec(path string, di fs.DirEntry, err error) error {
		if err != nil {
			log.Fatal(err)
		}

huangapple
  • 本文由 发表于 2022年7月8日 06:05:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/72904719.html
匿名

发表评论

匿名网友

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

确定