英文:
How do I check a file's permissions in linux using Go
问题
我正在学习Go语言,我想做的第一个项目是编写一个替代Linux find shell程序的程序。我在不到一个小时的时间内用Python写了一个替代程序。这是一个更大的挑战。
我遇到的问题是,当filepath.Walk
遍历我的文件系统时,它会在屏幕上输出一堆权限被拒绝的消息。我需要一种在filepath.Walk
操作文件之前检查文件权限的方法。
英文:
I'm learning Go and the first project I want to do is to write a replacement for the Linux find shell program. I wrote a replacement for it in python in less than an hour. This is a much bigger challenge.
The problem I'm having is as Goes filepath.Walk
traverses my file system it spits out a bunch of permission denied messages to the screen.
I need a way of checking the files permissions before filepath.Walk
touches them.
答案1
得分: 9
在go
中,文件权限是在os.FileMode
中定义的,底层类型是uint32
。根据文档:
FileMode表示文件的模式和权限位...
...
定义的文件模式位是FileMode的最高有效位。最低有效的九位是标准的Unix rwxrwxrwx权限。这些位的值应被视为公共API的一部分,并可用于线路协议或磁盘表示:它们不得更改,尽管可能会添加新的位。
您可以通过os.Stat
或os.LStat
函数检索FileMode
,它返回一个FileInfo
,例如:
info, err := os.Stat("文件/目录名称")
然后可以通过调用info.Mode()
来获取FileMode
。要检查权限,请对模式位执行按位操作,例如:
//检查“其他”权限
m := info.Mode()
if m&(1<<2) != 0 {
//其他用户具有读权限
} else {
//其他用户没有读权限
}
如果您使用filepath.Walk
函数访问目录/文件,由于WalkFunc
(Walk
的第二个参数)定义为
type WalkFunc func(path string, info os.FileInfo, err error) error
对于特定路径,WalkFunc
的第二个参数可用作FileInfo
,因此您可以直接使用info.Mode()
在传递给filepath.Walk
的闭包或函数的主体中检查权限,而无需调用os.Stat
或os.Lstat
。
英文:
In go
the file permission is defined in os.FileMode
in which the underlying type is an uint32
. From documentation:
> A FileMode represents a file's mode and permission bits...
...
The defined file mode bits are the most significant bits of the FileMode. The nine least-significant bits are the standard Unix rwxrwxrwx permissions. The values of these bits should be considered part of the public API and may be used in wire protocols or disk representations: they must not be changed, although new bits might be added.
You can retrieve the FileMode
through os.Stat
or os.LStat
function which returns a FileInfo
, e.g.
info, err := os.Stat("file/directory name")
then the FileMode
can be obtained by calling info.Mode()
. To check the permission, performs bitwise operation to the mode bits, e.g.
//Check 'others' permission
m := info.Mode()
if m&(1<<2) != 0 {
//other users have read permission
} else {
//other users don't have read permission
}
If you're visiting directory/file(s) using filepath.Walk
function, since the WalkFunc
(the second argument of Walk
) is defined as
type WalkFunc func(path string, info os.FileInfo, err error) error
the FileInfo
for certain path is available as the second argument of WalkFunc
, thus you can check the permission directly using info.Mode()
without calling os.Stat
or os.Lstat
inside the body of the closure or function passed to filepath.Walk.
答案2
得分: 5
你可以以字符串形式检索权限,例如:r,w,x。像这样:
func printPermissions(filename string) {
info, err := os.Stat(filename)
if err != nil {
panic(err)
}
mode := info.Mode()
fmt.Print("Owner: ")
for i := 1; i < 4; i++ {
fmt.Print(string(mode.String()[i]))
}
fmt.Print("\nGroup: ")
for i := 4; i < 7; i++ {
fmt.Print(string(mode.String()[i]))
}
fmt.Print("\nOther: ")
for i := 7; i < 10; i++ {
fmt.Print(string(mode.String()[i]))
}
}
英文:
You can retrieve the permissions in string form e.i: r, w, x. Like this:
func printPermissions(filename string) {
info, err := os.Stat(filename)
if err != nil {
panic(err)
}
mode := info.Mode()
fmt.Print("Owner: ")
for i := 1; i < 4; i++ {
fmt.Print(string(mode.String()[i]))
}
fmt.Print("\nGroup: ")
for i := 4; i < 7; i++ {
fmt.Print(string(mode.String()[i]))
}
fmt.Print("\nOther: ")
for i := 7; i < 10; i++ {
fmt.Print(string(mode.String()[i]))
}
}
答案3
得分: 0
对于Unix权限和现代Go语言,您可以使用字面量。
filePath := "/tmp/testfile"
fileStats, err := os.Stat(filePath)
if err != nil {
log.Fatalf("文件不存在:%v", err)
}
permissions := fileStats.Mode().Perm()
if permissions != 0o600 {
log.Fatalf("权限不正确 %s (0%o),必须为0600:%s", permissions, permissions, filePath)
}
// 检查特定权限:用户读取、用户写入
if permissions&0b110000000 == 0b110000000 {
fmt.Printf("用户具有读取和写入权限\n")
}
// 检查特定权限:用户写入
if permissions&0b010000000 == 0b010000000 {
fmt.Printf("用户具有写入权限\n")
}
// 检查特定权限:用户读取
// 为了更好的可读性,进行分解
if permissions&0b100_000_000 == 0b100_000_000 {
fmt.Printf("用户具有读取权限\n")
}
关于权限的位和八进制的详细解释
https://codereview.stackexchange.com/a/79100
英文:
For unix permissions and modern go you can use literals.
filePath := "/tmp/testfile"
fileStats, err := os.Stat(filePath)
if err != nil {
log.Fatalf("file does not exist: %v", err)
}
permissions := fileStats.Mode().Perm()
if permissions != 0o600 {
log.Fatalf("incorrect permisisons %s (0%o), must be 0600 for '%s'", permissions, permissions, filePath)
}
// check for specific permissions: user read, user write
if permissions&0b110000000 == 0b110000000 {
fmt.Printf("user has read and write permission\n")
}
// check for specific permission: user write
if permissions&0b010000000 == 0b010000000 {
fmt.Printf("user has write permission\n")
}
// check for specific permission: user read
// breakup for better readability
if permissions&0b100_000_000 == 0b100_000_000 {
fmt.Printf("user has read permission\n")
}
A nice explaination on permissions as bits and octal
https://codereview.stackexchange.com/a/79100
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论