我需要使用Go来获取给定文件的文件权限(特别是SUID位(。以下是一个示例文件的权限。
$ touch example_file.test
$ chmod 7777 example_file.test
$ ls -ltra example_file.test
-rwsrwsrwt 1 luke users 0 Feb 25 21:53 example_file.test
$ stat -c "%a %n" example_file.test
7777 example_file.test
这里有一个小程序来说明这个问题。
func main() {
info, _ := os.Stat("example_file.test")
fmt.Println(info.Mode().String()) // ugtrwxrwxrwx
fmt.Println(info.Mode().Perm().String()) // -rwxrwxrwx
fmt.Printf("permissions: %#on", info.Mode().Perm()) // permissions: 0777
}
由于ugtrwxrwxrwx != 0777
。
文档中的以下引用表明这可能是一个跨平台兼容性问题。
FileMode表示文件的模式和权限位。钻头具有在所有系统上使用相同的定义,以便获得有关文件的信息可以从一个系统移动到另一个系统。并非所有位都适用适用于所有系统。唯一需要的位是目录的ModeDir。
type FileMode uint32定义的文件模式位最多FileMode的有效位。九个最低有效位是标准Unix rwxrwxrwx权限。这些位的值应被视为公共API的一部分,并可用于电线协议或磁盘表示:尽管可以添加新的比特。
这是Go的限制吗?
值得注意的是,除了八进制表示不匹配之外,字符串表示也不匹配:
"-rwsrwsrwt" != "ugtrwxrwxrwx"`
这并不是由于Go实现的限制,而是以系统不可知的方式实现的结果。
来自FileMode
文档(强调矿(:
FileMode表示文件的模式和权限位。钻头具有在所有系统上使用相同的定义,以便获得有关文件的信息可以从一个系统移动到另一个系统并非所有位都适用适用于所有系统
因为实现不是为了模仿特定系统的行为,所以不能保证输出与给定环境中的本机工具匹配。然而,所有相关数据都是可以使用的。
如果你想模仿stat
的输出,你只需要编写一些逻辑就可以了
下面是一个处理八进制表示的快速示例:
package main
import (
"fmt"
"os"
)
func UnixPerm(m os.FileMode) (p uint32) {
p = uint32(m.Perm())
if m & os.ModeSetuid != 0 {
p |= 04000
}
if m & os.ModeSetgid != 0 {
p |= 02000
}
if m & os.ModeSticky != 0 {
p |= 01000
}
return p
}
func main() {
info, _ := os.Stat("example_file")
fmt.Printf("FileMode.Perm(): %04on", info.Mode().Perm())
fmt.Printf("UnixPerm(): %04on", UnixPerm(info.Mode()))
}
输出:
$ go run fileperm.go
FileMode.Perm(): 0777
UnixPerm(): 7777
$ stat --printf "Permissions: %an" example_file
Permissions: 7777
我需要使用golang来获得给定文件的文件权限(特别是SUID位(
好的,添加这个:fmt.Printf("File has SUID bit set: %tn", info.Mode()&os.ModeSetuid != 0)
golang结果不一致,因为ugtrwxrwxrwx!=0777
info.Mode()
和info.Mode().Perm()
是不同的东西,尽管它们是相关的。
CCD_ 7包含CCD_。CCD_ 9只是一个用恒定掩码CCD_。
这是go的限制吗?
无