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  }