问题
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