How to check if a file is executable in go?

断了今生、忘了曾经 提交于 2020-12-25 15:24:47

问题


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.


回答1:


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
}


来源:https://stackoverflow.com/questions/60128401/how-to-check-if-a-file-is-executable-in-go

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!