且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

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

更新时间:2023-11-25 23:05:10

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

他们的意思是:

  rwxrwxrwx 

前3位用于所有者,后3位用于组,后3位用于其他.

要确定文件的所有者是否可执行文件,请使用位掩码 0100 :

  func IsExecOwner(mode os.FileMode)bool {返回模式& 0100!= 0} 

类似地,如果要告诉组是否可执行,请使用位掩码 0010 :

  func IsExecGroup(mode os.FileMode)bool {返回模式& 0010!= 0} 

以及其他人,使用位掩码 0001 :

  func IsExecOther(mode os.FileMode)bool {返回模式& 0001!= 0} 

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

  func IsExecAny(mode os.FileMode)bool {返回模式& 0111!= 0} 

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

  func IsExecAll(mode os.FileMode)bool {返回模式& 0111 == 0111} 

How would I write a function to check whether a file is executable in Go? Given an os.FileInfo, I can get os.FileInfo.Mode(), but I stall out trying to parse the permission bits.

Test case:

#!/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

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"

I only care about Unix files, but extra points if the solution works for Windows as well.

Whether the file is executable is stored in the Unix permission bits (returned by FileMode.Perm() which are basically the lowest 9 bits (0777 octal bitmask). Note that since we're using bitmasks in below solutions that mask out other bits anyway, calling Perm() is not necessary.

Their meaning is:

rwxrwxrwx

Where the first 3 bits are for the owner, the next 3 are for the group and the last 3 bits are for other.

To tell if the file is executable by its owner, use bitmask 0100:

func IsExecOwner(mode os.FileMode) bool {
    return mode&0100 != 0
}

Similarly for telling if executable by the group, use bitmask 0010:

func IsExecGroup(mode os.FileMode) bool {
    return mode&0010 != 0
}

And by others, use bitmask 0001:

func IsExecOther(mode os.FileMode) bool {
    return mode&0001 != 0
}

To tell if the file is executable by any of the above, use bitmask 0111:

func IsExecAny(mode os.FileMode) bool {
    return mode&0111 != 0
}

To tell if the file is executable by all of the above, again use bitmask 0111 but check if the result equals to 0111:

func IsExecAll(mode os.FileMode) bool {
    return mode&0111 == 0111
}