如何在go中检查文件是否可执行?

Ste*_*alt 7 unix go

我将如何编写一个函数来检查文件在 Go 中是否可执行?给定os.FileInfo,我可以得到os.FileInfo.Mode(),但是我在尝试解析权限位时遇到了困难。

测试用例:

#!/usr/bin/env bash
function setup() {
  mkdir -p test/foo/bar
  touch test/foo/bar/{baz.txt,quux.sh}
  chmod +x test/foo/bar/quux.sh
}

function teardown() { rm -r ./test }

setup
Run Code Online (Sandbox Code Playgroud)
import (
    "os"
    "path/filepath"
    "fmt"
)

func IsExectuable(mode os.FileMode) bool {
    // ???
}

func main() {
    filepath.Walk("test", func(path string, info os.FileInfo, err error) error {
        if err != nil || info.IsDir() {
            return err
        }
        fmt.Printf("%v %v", path, IsExectuable(info.Mode().Perm()))
    }
}
// should print "test/foo/bar/baz.txt false"
//              "test/foo/bar/quux.txt true"
Run Code Online (Sandbox Code Playgroud)

我只关心 Unix 文件,但如果该解决方案也适用于 Windows,则额外加分。

icz*_*cza 8

文件是否可执行存储在Unix 权限位(由其返回的FileMode.Perm()基本上是最低 9 位(0777八进制位掩码)。请注意,由于我们在下面的解决方案中使用位掩码来屏蔽其他位,Perm()因此不需要调用。

它们的含义是:

rwxrwxrwx
Run Code Online (Sandbox Code Playgroud)

其中前 3 位用于所有者,接下来的 3 位用于组,后 3 位用于其他。

要判断文件是否可由其所有者执行,请使用位掩码0100

func IsExecOwner(mode os.FileMode) bool {
    return mode&0100 != 0
}
Run Code Online (Sandbox Code Playgroud)

同样,如果要告诉组是否可执行,请使用位掩码0010

func IsExecGroup(mode os.FileMode) bool {
    return mode&0010 != 0
}
Run Code Online (Sandbox Code Playgroud)

和其他人,使用位掩码0001

func IsExecOther(mode os.FileMode) bool {
    return mode&0001 != 0
}
Run Code Online (Sandbox Code Playgroud)

要判断文件是否可由上述任何一个执行,请使用位掩码0111

func IsExecAny(mode os.FileMode) bool {
    return mode&0111 != 0
}
Run Code Online (Sandbox Code Playgroud)

要判断文件是否可以被上述所有文件执行,再次使用位掩码0111但检查结果是否等于0111

func IsExecAll(mode os.FileMode) bool {
    return mode&0111 == 0111
}
Run Code Online (Sandbox Code Playgroud)

  • 用于检查当前用户(基于真实 UID 和 GID)是否可以执行文件的 POSIX 系统调用是 [`access`](https://pubs.opengroup.org/onlinepubs/9699919799/functions/access.html)与“X_OK”。在支持 ACL 的平台(例如 Linux)上,这还应该考虑文件的 ACL。 (2认同)