github.com/teddydd/sh@v2.6.4+incompatible/fileutil/file.go (about) 1 // Copyright (c) 2016, Daniel Martà <mvdan@mvdan.cc> 2 // See LICENSE for licensing information 3 4 // Package fileutil contains code to work with shell files, also known 5 // as shell scripts. 6 package fileutil 7 8 import ( 9 "os" 10 "regexp" 11 "strings" 12 ) 13 14 var ( 15 shebangRe = regexp.MustCompile(`^#!\s?/(usr/)?bin/(env\s+)?(sh|bash)\s`) 16 extRe = regexp.MustCompile(`\.(sh|bash)$`) 17 ) 18 19 // HasShebang reports whether bs begins with a valid sh or bash shebang. 20 // It supports variations with /usr and env. 21 func HasShebang(bs []byte) bool { 22 return shebangRe.Match(bs) 23 } 24 25 // ScriptConfidence defines how likely a file is to be a shell script, 26 // from complete certainty that it is not one to complete certainty that 27 // it is one. 28 type ScriptConfidence int 29 30 const ( 31 ConfNotScript ScriptConfidence = iota 32 ConfIfShebang 33 ConfIsScript 34 ) 35 36 // CouldBeScript reports how likely a file is to be a shell script. It 37 // discards directories, symlinks, hidden files and files with non-shell 38 // extensions. 39 func CouldBeScript(info os.FileInfo) ScriptConfidence { 40 name := info.Name() 41 switch { 42 case info.IsDir(), name[0] == '.': 43 return ConfNotScript 44 case info.Mode()&os.ModeSymlink != 0: 45 return ConfNotScript 46 case extRe.MatchString(name): 47 return ConfIsScript 48 case strings.IndexByte(name, '.') > 0: 49 return ConfNotScript // different extension 50 case info.Size() < int64(len("#/bin/sh\n")): 51 return ConfNotScript // cannot possibly hold valid shebang 52 default: 53 return ConfIfShebang 54 } 55 }