Documentation
¶
Overview ¶
Package stank provides primitives for analyzing programming scripts, especially shell scripts.
Index ¶
- Constants
- Variables
- func GNUAwkCheckSyntax(smell Smell) error
- func GoCheckSyntax(smell Smell) error
- func Ignore(pth string) bool
- func PHPCheckSyntax(smell Smell) error
- func POSIXShCheckSyntax(smell Smell) error
- func PerlishCheckSyntax(smell Smell) error
- func PythonCheckSyntax(smell Smell) error
- func UnixCheckSyntax(smell Smell) error
- type Smell
- type SniffConfig
- type Sniffer
Constants ¶
const Version = "0.0.44"
Version is semver.
Variables ¶
var AltExtensions = sync.OnceValue(func() map[string]bool { return map[string]bool{ ".csh": true, ".cshrc": true, ".elv": true, ".etsh": true, ".fish": true, ".fishrc": true, ".ion": true, ".ionrc": true, ".lksh": true, ".rc": true, ".rcrc": true, ".tcsh": true, ".tcshrc": true, ".tsh": true, } })
AltExtensions provides some alternative shell script file extensions.
var AltFilenames = sync.OnceValue(func() map[string]bool { return map[string]bool{ "csh.login": true, "csh.logout": true, "rc.elv": true, } })
AltFilenames provides some alternative shell script profile filenames.
var AltInterpreters = sync.OnceValue(func() map[string]bool { return map[string]bool{ "csh": true, "elvish": true, "etsh": true, "fish": true, "ion": true, "lksh": true, "rc": true, "tcsh": true, "tsh": true, } })
AltInterpreters provides some alternative shell interpreters.
var Boms = sync.OnceValue(func() [][]byte { return [][]byte{ {0x00, 0x00, 0xFE, 0xFF}, {0x2B, 0x2F, 0x76, 0x2B}, {0x2B, 0x2F, 0x76, 0x2F}, {0x2B, 0x2F, 0x76, 0x38}, {0x2B, 0x2F, 0x76, 0x39}, {0xFE, 0xFF}, {0xFF, 0xBB, 0xBF}, {0xFF, 0xFE}, {0xFF, 0xFE, 0x00, 0x00}, {0x0E, 0xFE, 0xFF}, {0x2B, 0x2F, 0x76, 0x38, 0x3D}, {0x84, 0x31, 0x95, 0x33}, {0xDD, 0x73, 0x66, 0x73}, {0xF7, 0x64, 0x4C}, {0xFB, 0xEE, 0x28}, } })
Boms() provides a set of known Byte Order mark sequences. See https://en.wikipedia.org/wiki/Byte_order_mark for more information.
var FullBashInterpreters = sync.OnceValue(func() map[string]bool { return map[string]bool{ "bash": true, "bash4": true, } })
FullBashInterpreters note when a shell has the basic modern bash features, as opposed to subsets such as ash, dash, posh, ksh, zsh.
var Ignores = sync.OnceValue(func() []string { return []string{ ".git", ".venv", "node_modules", "vendor", "vendor-rust", } })
Ignores generates common exclusion file paths.
var Interpreter2SyntaxValidator = sync.OnceValue(func() map[string]func(Smell) error { return map[string]func(Smell) error{ "ash": UnixCheckSyntax, "bash": UnixCheckSyntax, "bash4": UnixCheckSyntax, "bmake": UnixCheckSyntax, "bosh": UnixCheckSyntax, "csh": UnixCheckSyntax, "dash": UnixCheckSyntax, "elvish": UnixCheckSyntax, "fish": UnixCheckSyntax, "gawk": GNUAwkCheckSyntax, "generic-sh": POSIXShCheckSyntax, "gmake": UnixCheckSyntax, "go": GoCheckSyntax, "iojs": PerlishCheckSyntax, "ksh": UnixCheckSyntax, "ksh88": UnixCheckSyntax, "ksh93": UnixCheckSyntax, "lksh": UnixCheckSyntax, "make": UnixCheckSyntax, "mksh": UnixCheckSyntax, "node": PerlishCheckSyntax, "oksh": UnixCheckSyntax, "oil": UnixCheckSyntax, "osh": UnixCheckSyntax, "pdksh": UnixCheckSyntax, "perl": PerlishCheckSyntax, "perl6": PerlishCheckSyntax, "php": PHPCheckSyntax, "pmake": UnixCheckSyntax, "posh": UnixCheckSyntax, "python": PythonCheckSyntax, "python3": PythonCheckSyntax, "rc": UnixCheckSyntax, "rksh": UnixCheckSyntax, "ruby": PerlishCheckSyntax, "sh": POSIXShCheckSyntax, "tcsh": UnixCheckSyntax, "yash": UnixCheckSyntax, "ysh": UnixCheckSyntax, "zsh": UnixCheckSyntax, } })
Interpreter2SyntaxValidator provides syntax validator delegates, if one is available.
var InterpretersToPosixyness = sync.OnceValue(func() map[string]bool { return map[string]bool{ "ash": true, "awk": false, "bash": true, "bash4": true, "bosh": true, "csh": false, "dash": true, "elvish": false, "etsh": false, "expect": false, "fish": false, "gawk": false, "hsh": true, "ion": false, "jruby": false, "jython": false, "ksh": true, "ksh88": true, "ksh93": true, "lksh": false, "lua": false, "mksh": true, "node": false, "oksh": true, "oil": true, "osh": true, "pdksh": true, "perl": false, "perl6": false, "php": false, "posh": true, "python": false, "rc": false, "rksh": true, "ruby": false, "sed": false, "sh": true, "stash": false, "swift": false, "tclsh": false, "tcsh": false, "tsh": false, "yash": true, "ysh": false, "zsh": true, } })
InterpretersToPosixyness provides a fairly exhaustive map of interpreters to whether or not the interpreter is a POSIX compatible shell. Newly minted interpreters can be added by stank contributors.
var KshInterpreters = sync.OnceValue(func() map[string]bool { return map[string]bool{ "ksh": true, "ksh88": true, "ksh93": true, "mksh": true, "oksh": true, "pdksh": true, "rksh": true, } })
KshInterpreters note when a shell is a member of the modern ksh family.
var LowerExtensionsToConfig = sync.OnceValue(func() map[string]bool { return map[string]bool{ ".ashrc": true, ".bash_login": true, ".bash_logout": true, ".bash_profile": true, ".bashrc": true, ".cshrc": true, ".dashrc": true, ".fishrc": true, ".ionrc": true, ".kshrc": true, ".profile": true, ".rcrc": true, ".shinit": true, ".shrc": true, ".tcshrc": true, ".zlogin": true, ".zlogout": true, ".zprofile": true, ".zshenv": true, ".zshrc": true, } })
LowerExtensionsToConfig() provides a fairly exhaustive map of lowercase file extensions to whether or not they represent shell script configurations. Newly minted extensions can be added by stank contributors.
var LowerExtensionsToInterpreter = sync.OnceValue(func() map[string]string { return map[string]string{ ".ashrc": "ash", ".awk": "awk", ".bash": "bash", ".bash_login": "bash", ".bash_logout": "bash", ".bash_profile": "bash", ".bashrc": "bash", ".bsdmakefile": "bmake", ".csh": "csh", ".cshrc": "csh", ".dash": "dash", ".dashrc": "dash", ".elv": "elvish", ".fish": "fish", ".fishrc": "fish", ".gawk": "gawk", ".gnumakefile": "gmake", ".hsh": "hsh", ".ion": "ion", ".ionrc": "ion", ".ksh": "ksh", ".ksh88": "ksh", ".ksh93": "ksh93", ".ksh93rc": "ksh93", ".kshrc": "ksh", ".lkshrc": "lksh", ".lua": "lua", ".makefile": "make", ".mf": "make", ".mksh": "mksh", ".mkshrc": "mksh", ".osh": "osh", ".pdksh": "pdksh", ".pdkshrc": "pdksh", ".php": "php", ".pmakefile": "pmake", ".poshrc": "posh", ".profile": "sh", ".rc": "rc", ".rcrc": "rc", ".sed": "sed", ".sh": "sh", ".shinit": "sh", ".shrc": "sh", ".tcsh": "tcsh", ".tcshrc": "tcsh", ".ysh": "ysh", ".zlogin": "zsh", ".zlogout": "zsh", ".zprofile": "zsh", ".zsh": "zsh", ".zshenv": "zsh", ".zshprofile": "zsh", ".zshrc": "zsh", "ash": "ash", } })
LowerExtensionsToInterpreter() is a fairly exhaustive map of lowercase file extensions to their corresponding interpreters. Newly minted config extensions can be added by stank contributors.
var LowerExtensionsToPosixyness = sync.OnceValue(func() map[string]bool { return map[string]bool{ ".ada": false, ".ash": true, ".bash": true, ".bash4": true, ".bash_login": true, ".bash_logout": true, ".bash_profile": true, ".bashrc": true, ".bat": false, ".bin": false, ".bmp": false, ".bosh": true, ".c": false, ".cl": false, ".cmd": false, ".conf": false, ".csh": false, ".cshrc": false, ".dash": true, ".doc": false, ".docx": false, ".ds_store": false, ".e": false, ".elv": false, ".erl": false, ".escript": false, ".etsh": false, ".exe": false, ".expect": false, ".fish": false, ".flv": false, ".fth": false, ".gif": false, ".gitignore": false, ".gitkeep": false, ".gitmodules": false, ".groovy": false, ".hsh": true, ".ionrc": false, ".j": false, ".jpeg": false, ".jpg": false, ".js": false, ".json": false, ".ksh": true, ".ksh88": true, ".ksh93": true, ".kshrc": true, ".lisp": false, ".lksh": false, ".log": false, ".lua": false, ".markdown": false, ".md": false, ".mf": false, ".mksh": true, ".mov": false, ".mp3": false, ".mp4": false, ".oksh": true, ".pdf": false, ".pdksh": true, ".php": false, ".pike": false, ".pl": false, ".png": false, ".posh": true, ".properties": false, ".psh": false, ".py": false, ".pyw": false, ".rb": false, ".rc": false, ".rksh": true, ".rkt": false, ".scala": false, ".sf": false, ".sh": true, ".shinit": true, ".shrc": true, ".svg": false, ".swp": false, ".tcsh": false, ".tcshrc": false, ".tiff": false, ".tsh": false, ".txr": false, ".txt": false, ".vbs": false, ".wav": false, ".xml": false, ".yaml": false, ".yash": true, ".yml": false, ".zkl": false, ".zlogin": true, ".zlogout": true, ".zprofile": true, ".zsh": true, ".zshenv": true, ".zshrc": true, } })
LowerExtensionsToPosixyness() provides a fairly exhaustive map of lowercase file extensions to whether or not they represent POSIX shell scripts. Newly minted extensions can be added by stank contributors.
var LowerFilenamesToConfig = sync.OnceValue(func() map[string]bool { return map[string]bool{ "bash_login": true, "bash_logout": true, "csh.login": true, "csh.logout": true, "login": true, "logout": true, "oilrc": true, "oshrc": true, "profile": true, "rc.elv": true, "rcrc": true, "shinit": true, "shrc": true, "tcsh.login": true, "tcsh.logout": true, "yshrc": true, "zlogin": true, "zlogout": true, "zprofile": true, "zshenv": true, "zshrc": true, } })
LowerFilenamesToConfig() provides a fairly exhaustive map of lowercase filenames to whether or not they represent shell script configurations. Newly minted config filenames can be added by stank contributors.
var LowerFilenamesToInterpreter = sync.OnceValue(func() map[string]string { return map[string]string{ ".ashrc": "ash", ".bashrc": "bash", ".cshrc": "csh", ".dashrc": "dash", ".fishrc": "fish", ".ionrc": "ion", ".ksh93rc": "ksh93", ".kshrc": "ksh", ".lkshrc": "lksh", ".login": "sh", ".logout": "sh", ".mkshrc": "mksh", ".pdkshrc": "pdksh", ".poshrc": "posh", ".rcrc": "rc", ".shinit": "sh", ".shrc": "sh", ".tcshrc": "tcsh", ".zlogin": "zsh", ".zlogout": "zsh", ".zprofile": "zsh", ".zshenv": "zsh", ".zshrc": "zsh", "bsdmakefile": "bmake", "csh.login": "csh", "csh.logout": "csh", "gnumakefile": "gmake", "makefile": "make", "oilrc": "osh", "oshrc": "osh", "pmakefile": "pmake", "profile": "sh", "rc.elv": "elvish", "tcsh.login": "tcsh", "tcsh.logout": "tcsh", "yshrc": "ysh", "zlogin": "zsh", "zlogout": "zsh", "zprofile": "zsh", "zshenv": "zsh", "zshrc": "zsh", } })
LowerFilenamesToInterpreter() provides a fairly exhaustive map of lowercase filenames to their corresponding interpreters. Newly minted config filenames can be added by stank contributors.
var LowerFilenamesToPosixyness = sync.OnceValue(func() map[string]bool { return map[string]bool{ ".profile": true, "bash_login": true, "bash_logout": true, "changelog": false, "csh.login": false, "csh.logout": false, "login": true, "logout": true, "makefile": false, "oilrc": true, "oshrc": true, "profile": true, "rc.elv": false, "rcrc": false, "readme": false, "shinit": true, "shrc": true, "tcsh.login": false, "tcsh.logout": false, "thumbs.db": false, "yshrc": false, "zlogin": true, "zlogout": true, "zprofile": true, "zshenv": true, "zshrc": true, } })
LowerFilenamesToPosixyness() provides a fairly exhaustive map of lowercase filenames to whether or not they represent POSIX shell scripts. Newly minted config filenames can be added by stank contributors.
var LowerMachineExtensions = sync.OnceValue(func() map[string]bool { return map[string]bool{ ".sample": true, } })
LowerMachineExtensions() provides a rather truncated survey of machine-generated file extensions likely to not be edited directly by most shell script authors.
Functions ¶
func GNUAwkCheckSyntax ¶ added in v0.0.17
GNUAwkCheckSyntax validates syntax for GNU awk files.
func GoCheckSyntax ¶ added in v0.0.17
GoCheckSyntax validates syntax for Go.
func PHPCheckSyntax ¶ added in v0.0.17
PHPCheckSyntax validates syntax for PHP.
func POSIXShCheckSyntax ¶ added in v0.0.17
POSIXShCheckSyntax validates syntax for strict POSIX sh compliance.
func PerlishCheckSyntax ¶ added in v0.0.17
PerlishCheckSyntax validates syntax for Perl, Ruby, and Node.js.
func PythonCheckSyntax ¶ added in v0.0.17
PythonCheckSyntax validates syntax for Python.
func UnixCheckSyntax ¶ added in v0.0.17
UnixCheckSyntax validates syntax for the wider UNIX shell family.
Types ¶
type Smell ¶
type Smell struct {
// Path denotes a file path.
Path string `json:"path"`
// Filename denotes a relative file path.
Filename string `json:"filename"`
// Basename denotes filename component to the left of extensions.
Basename string `json:"basename"`
// Extension denotes a file extension.
Extension string `json:"extension"`
// Symlink denotes whether an entry is a symbolic link.
Symlink bool `json:"symlink"`
// Shebang denotes an interpreter line.
Shebang string `json:"shebang"`
// Interpreter denotes a REPL.
Interpreter string `json:"interpreter"`
// InterpreterFlags collects CLI arguments supplied to interpreters.
InterpreterFlags []string `json:"interpreter_flags"`
// LineEnding denotes line terminators.
LineEnding string `json:"line_ending"`
// FinalEOL denotes whether the file applies a final End Of Line terminator.
FinalEOL *bool `json:"final_eol"`
// ContainsCR denotes whether the file contains carriage returns.
ContainsCR bool `json:"contains_cr"`
// Permissions dentotes chmod bits.
Permissions os.FileMode `json:"permissions"`
// Directory denotes whether the file path is a directory.
Directory bool `json:"directory"`
// OwnerExecutable denotes whether the file has owner executable chmod bits.
OwnerExecutable bool `json:"owner_executable"`
// Library denotes whether the script seems to be a library / sourceable script.
Library bool `json:"library"`
// BOM denotes whether the file contents feature an opening BOM marker.
BOM bool `json:"bom"`
// POSIXy denotes whether the file path appears to be a POSIX family shell script.
POSIXy bool `json:"posixy"`
// Bash denotes whether the file path appers to be a bash family script.
Bash bool `json:"bash"`
// Ksh denotes whether the file path appears to be a ksh family script.
Ksh bool `json:"ksh"`
// AltShellScript denotes whether the file path appears to be a non-POSIX family shell script.
AltShellScript bool `json:"alt_shell_script"`
// CoreConfiguration denotes whether the file path represents configuration files.
CoreConfiguration bool `json:"core_configuration"`
// MachineGenerated denotes whether the code is likely to have nonmanual origins.
MachineGenerated bool `json:"machine_generated"`
}
Smell describes the overall impression of a file's POSIXyness, using several factors to determine with a reasonably high accuracy whether or not the file is a POSIX compatible shell script.
An idiomatic shebang preferably leads the file, such as #!/bin/bash, #!/bin/zsh, #!/bin/sh, etc. This represents good form when writing shell scripts, in particular ensuring that the script will be evaluated by the right interpreter, even if the extension is omitted or a generic ".sh". Shell scripts, whether executable applications or source'able libraries, should include a shebang. One attribute not analyzed by this library is unix file permission bits. Application shell scripts should set the executable bit(s) to 1, while shell scripts intended to be sourced or imported should not set these bits. Either way, the bits have hardly any correlation with the POSIXyness of a file, as the false positives and false negatives are too frequent.
Common filenames for POSIX compatible scripts include .profile, .login, .bashrc, .bash_profile, .zshrc, .kshrc, .envrc*, and names for git hooks. The stank library will catalog some of these standard names, though application-specific filenames are various and sundry. Ultimately, all files containing POSIX compatible shell content should include a shebang, to help interpreters, editors, and linters identify POSIX shell content.
File extension is another way to estimate a script's POSIXyness. For example, ".bash", ".ksh", ".posh", ".sh", etc. would each indicate a POSIX compatible shell script, whereas ".py", ".pl", ".rb", ".csh", ".rc", and so on would indicate nonPOSIX script. File extensions are often omitted or set to a generic ".sh" for command line applications, in which case the extension is insufficient for establishing the POSIX vs. nonPOSIX nature of the script. This is why shebangs are so important; while file extensions can be helpful, shell scripts really rely moreso on the shebang for self identification, and extensions aren't always desirable, as unix CLI applications prefer to omit the extension from the filename for brevity. Note that some filenames such as ".profile" may be logically considered to have basename "" (blank) and extension ".profile", or basename ".profile" with extension ".profile", or else basename ".profile" and extension "" (blank). In practice, Go treats both the basename and extension for these kinds of files as containing ".profile", and Smell will behave accordingly.
File encoding also sensitive for shell scripts. Generally, ASCII subset is recommended for maximum portability. If your terminal supports it, the LANG environment variable can be altered to accept UTF-8 and other encodings, enabling raw UTF-8 data to be used in script contents. However, this restricts your scripts to running only on systems explicitly configured to match the encoding/locale of your script; and tends to furter limit the platforms for your script to specifically GNU libc Linux distributions, so using nonASCII content in your scripts is inadvisable. Shell scripts conforming to POSIX should really use pure ASCII characters. NonUTF-8 encodings such as UTF-16, UTF-32, and even nonUnicode encodings like EBCDIC, Latin1, and KOI8-R usually indicate a nonPOSIX shell script, even a localization file or other nonscript. These encodings are encountered less often than ASCII and UTF-8, and are generally considered legacy formats. For performance reasons, the stank library will not attempt to discern the exact encoding of a file, but merely report whether the file leads with a byte order marker such as 0xEFBBBF (UTF-8) or 0xFEFF (UTF-16, UTF-32). If BOM, then the file is Unicode, which may lead to a stank warning, as POSIX shell scripts are best written in pure ASCII, for maximum cross-platform compatibliity. Boms() are outside of the 127 max integer range for ASCII values, so a file with a BOM is likely not a POSIX shell script, while a file without a BOM may be a POSIX shell script.
Line endings for POSIX shell scripts should LF="\n" in C-style notation. Alternative line endings such as CRLF="\r\n", ancient Macintosh CR="\r", and bizarre forms like vertical tab (ASCII code 0x0B) or form feed (ASCII code 0x0C) are possible in a fuzzing sense, but may lead to undefined behavior depending on the particular shell interpreter. For the purposes of identifying POSIX vs nonPOSIX scripts, a Smell will look for LF, CRLF, and CR; and ignore the presence or absence of these other exotic whitespace separators. NonPOSIX scripts written in Windows, such as Python and Ruby scripts, are ideally written with LF line endings, though it is common to observe CRLF endings, as Windows users more frequently invoke these as "python script.py", "ruby script.rb", rather than the bare "script" or dot slash "./script" forms typically used by unix administrators. For performance, the stank library will not report possible multiple line ending styles, such as poorly formatted text files featuring both CRLF and LF line endings. The library will simply report the first confirmed line ending style.
Moreover, POSIX line ending LF is expected at the end of a text file, so a final end of line character "\n" is good form. Common unix utilities such as cat expect this final EOL, and will misrender the successive shell prompt when processing files that omit the final EOL. Make expects a final EOL, and gcc may produce malformed .c code if the .h header files neglect to include a final EOL. For performance reasons, the stank library will not attempt to read the entire file to report on the presence/absence of a final EOL. Shell script authors should nonetheless configure their text editors to consistently include a final EOL in the vast majority of text file formats.
A POSIXy flag indicates that, to the best of the stank library's ability, a file is identified as either very likely a POSIX shell script, or something else. Something else encompasses nonPOSIX shell scripts such as Csh, Tcsh, Python, Ruby, Lua scripts; also encompasses nonscript files such as multimedia images, audio, rich text documents, machine code, and other nonUTF-8, nonASCII content.
Scripts referencing "sh" are generally considered to be POSIX sh. Ignoring unmarked legacy Thompson sh scripts.
Unknown, even more obscure languages are assumed to be non-POSIXY.
Languages with duplicate names (e.g. oil shell osh vs. OpenSolaris oil shell) are generally assumed not to be POSIXy. Unable to disambiguate without more specific information (shebang names, file extentions).
func (Smell) MarshalJSON ¶ added in v0.0.37
MarshalJSON encodes a Smell as JSON.
func (*Smell) UnmarshalJSON ¶ added in v0.0.37
UnmarshallJSON decodes a Smell from JSON.
type SniffConfig ¶ added in v0.0.9
type SniffConfig struct {
// EOLCheck analyzes End Of Line termination.
EOLCheck bool
// CRCheck analyzes line terminations.
CRCheck bool
}
SniffConfig bundles together the various options when sniffing files for POSIXyNESS.
type Sniffer ¶ added in v0.0.42
type Sniffer struct {
// AltExtensions caches metadata tables.
AltExtensions map[string]bool
// AltFilenames caches metadata tables.
AltFilenames map[string]bool
// AltInterpreters caches metadata tables.
AltInterpreters map[string]bool
// Boms caches metadata tables.
Boms [][]byte
// FullBashInterpreters caches metadata tables.
FullBashInterpreters map[string]bool
// InterpretersToPosixyness caches metadata tables.
InterpretersToPosixyness map[string]bool
// KshInterpreters caches metadat tables.
KshInterpreters map[string]bool
// LowerExtensionsToConfig caches metadata tables.
LowerExtensionsToConfig map[string]bool
// LowerExtensionsToInterpreter caches metadata tables.
LowerExtensionsToInterpreter map[string]string
// LowerExtensionsToPosixyness caches metadata tables.
LowerExtensionsToPosixyness map[string]bool
// LowerFilenamesToConfig caches metadata tables.
LowerFilenamesToConfig map[string]bool
// LowerFilenamesToInterpreter caches metadata tables.
LowerFilenamesToInterpreter map[string]string
// LowerFilenamesToPosixyness caches metadata tables.
LowerFilenamesToPosixyness map[string]bool
// LowerMachineExtensions caches metadata tables.
LowerMachineExtensions map[string]bool
}
Sniffer analyzes files.
func (Sniffer) IsAltShellScript ¶ added in v0.0.42
IsAltShellScript returns whether a smell represents a non-POSIX, but nonetheless similar kind of lowlevel shell script language.
func (Sniffer) Sniff ¶ added in v0.0.42
func (o Sniffer) Sniff(pth string, config SniffConfig) (Smell, error)
Sniff analyzes the holistic smell of a given file path, returning a Smell record of key indicators tending towards either POSIX compliance or noncompliance, including a flag for the final "POSIXy" trace scent of the file.
For performance, if the scent of one or more attributes obviously indicates POSIX or nonPOSIX, Sniff() may short-circuit, setting the POSIXy flag and returning a record with some attributes set to zero value.
Polyglot and multiline shebangs are technically possible in languages that do not support native POSIX-style shebang comments ( see https://rosettacode.org/wiki/Multiline_shebang ). However, Sniff() can reliably identify only ^#!.+$ POSIX-style shebangs, and will populate the Shebang field accordingly.
If an I/O problem occurs during analysis, an error value will be set. Otherwise, the error value will be nil.
Directories
¶
| Path | Synopsis |
|---|---|
|
cmd
|
|
|
funk
command
Package main implements a shell script linter CLI application, with unique checks on fundamental portability, safety, and security concerns.
|
Package main implements a shell script linter CLI application, with unique checks on fundamental portability, safety, and security concerns. |
|
stank
command
Package main implements a CLI application to recursively identify POSIX shell scripts in large, complex directories.
|
Package main implements a CLI application to recursively identify POSIX shell scripts in large, complex directories. |
|
stink
command
Package main implements a CLI application for identifying script metadata.
|
Package main implements a CLI application for identifying script metadata. |