STANK ist eine Bibliothek und Sammlung von Befehlszeilen -Dienstprogrammen zum Schnüffeln von Dateien, um Shell -Skripte wie Bash, SH, ZSH, KSH und so weiter zu identifizieren, diese funky Barmfresh -Gäste von Garbaggio. im Vergleich zu anderen schmackhafteren Dateien wie RB, PY, PL.
Ob Sie es glauben oder nicht, Shell -Skripte sind bekanntermaßen schwer gut zu schreiben, sodass ein Entwickler entweder Shell -Skripte in sichereren Sprachen oder Wargame -Ihre Skripte mit einer Armada von Lintern schreiben kann. Das Problem ist, dass man bei großen Projekten nie zu sicher sein kann, welche Dateien ehrlich zu Dog Possix konforme Shell -Skripte sind und welche Pretenders sind. CSH, TCSH, Fisch, Ion, RC und die meisten anderen Nicht -Deckungsfleischbücher sind in der Regel nicht kompatibel. Wenn Sie geeky genug sind, um bisher gefolgt zu sein, lassen Sie uns Crackalackin mit einigen fruchtigen Beispielen verdammt!
Das STANK -System umfasst die Stank -Go -Bibliothek sowie mehrere Befehlszeilen -Dienstprogramme. Die stank Anwendung scannt Verzeichnisse und Dateien für von POSIX abgeleitete Shell-Skripte und druckt ihre Pfade, die als bequemer eigenständiger Filter für die Linie großer Sammlungen von Quellcode konzipiert wurden.
$ cd examples
$ stank .
.profile
.shrc
.zlogin
... Die stank -Befehlszeile -Dienstprogramme sucht Dateipfade für Shell -Skripte, die möglicherweise das Leinen rechtfertigen.
STANK integriert sich in externe Linter und trägt dazu bei, dass sie einen fokussierteren Satz von Dateipfaden in größeren Projektverzeichnissen ernähren.
$ stank -print0 . | xargs -0 -n 1 shellcheck
In welcome.sh line 1:
#!bash
^----^ SC2239 (error): Ensure the shebang uses an absolute path to the interpreter.
For more information:
https://www.shellcheck.net/wiki/SC2239 -- Ensure the shebang uses an absolu... Maschinengenerierte Dateien, einschließlich Git Hook Standard *.sample -Dateien, werden automatisch übersprungen.
Weitere Optionen finden Sie in stank -help .
https://github.com/mcandre/stank/releases
$ go install github.com/mcandre/stank/...@latesthttps://pkg.go.dev/github.com/mcandre/stank
Die funk -Linter berichten von seltsamen Gerüchen, die von Skripten wie unsachgemäßen Zeilenenden ausgehen, das Vorhandensein von Byte -Order -Marker in einigen Unicode -Skripten.
$ funk examples
Ambiguous launch style. Either feature a file extensions, or else feature executable bits: examples/.shrc
Tokenize like `unset IFS` at the top of executable scripts: examples/.shrc
Control program flow like `set -euf` at the top of executable scripts: examples/.shrc
Tokenize like `unset IFS` at the top of executable scripts: examples/badconfigs/zprofile
Control program flow like `set -euf` at the top of executable scripts: examples/badconfigs/zprofile
Missing shebang: examples/blank.bash
Traps may reset in subshells: examples/cleanup.sh
Missing shebang: examples/goodbye.sh
Missing shebang: examples/greetings.bash
Control program flow like `set -euf` at the top of executable scripts: examples/hello-commented
$ funk -modulino examples
Configuration features shebang: examples/badconfigs/.bash_profile
Configuration features executable permissions: examples/badconfigs/zprofile
Missing final end of line sequence: examples/blank.bash
Missing shebang: examples/blank.bash
Interpreter mismatch between shebang and extension: examples/derp.zsh
Missing shebang: examples/greetings.bash
Missing final end of line sequence: examples/hello-crlf.sh
CR/CRLF line ending detected: examples/hello-crlf.sh
Modulino ambiguity. Either have owner executable permissions with no extension, or else remove executable bits and use an extension like .lib.sh: examples/hello-crlf.sh
Modulino ambiguity. Either have owner executable permissions with no extension, or else remove executable bits and use an extension like .lib.sh: examples/howdy
Missing shebang: examples/howdy.zsh
Missing shebang: examples/just-eol.bash
Modulino ambiguity. Either have owner executable permissions with no extension, or else remove executable bits and use an extension like .lib.sh: examples/lo
Missing final end of line sequence: examples/lo-cr.csh
CR/CRLF line ending detected: examples/lo-cr.csh
Modulino ambiguity. Either have owner executable permissions with no extension, or else remove executable bits and use an extension like .lib.sh: examples/pipefail
Modulino ambiguity. Either have owner executable permissions with no extension, or else remove executable bits and use an extension like .lib.sh: examples/shout.sh
Modulino ambiguity. Either have owner executable permissions with no extension, or else remove executable bits and use an extension like .lib.sh: examples/wednesday
Modulino ambiguity. Either have owner executable permissions with no extension, or else remove executable bits and use an extension like .lib.sh: examples/wednesday-bom
Leading BOM reduces portability: examples/wednesday-bom
Modulino ambiguity. Either have owner executable permissions with no extension, or else remove executable bits and use an extension like .lib.sh: examples/welcome
$ funk -help
-cr
Report presence/absence of final end of line sequence (default true)
-eol
Report presence/absence of final end of line sequence (default true)
-help
Show usage information
-modulino
Enforce strict separation of application scripts vs. library scripts
-version
Show version information Sowohl stank als auch funk können auch niedrige und nicht -posix -Skripte ausgewählt werden, wie z. B. CSH/TCSH -Skripte, die in FreeBSD verwendet werden.
Beachten Sie, dass Funk nicht zuverlässig vor fehlenden Shebangs warnen kann, wenn auch die Erweiterung fehlt. In der Regel verwenden Skriptautoren das eine oder andere, um Dateien als Shell -Skripte zu markieren. Da es sowohl ein Shebang als auch eine Dateierweiterung fehlt, kann eine Datei für viele Sprachen Code enthalten, was es schwierig macht, die Possixy -Natur des Code zu bestimmen. Selbst wenn ein erschöpfender Satz von ASTs angewendet wird, um den Dateiinhalt auf die syntaktische Gültigkeit über die Dutzenden verfügbarer Shell -Sprachen zu testen, besteht in kürzeren Dateien eine starke Möglichkeit, dass der Inhalt lediglich übrigens gültige Skriptsyntax ist, obwohl die Absicht der Datei nicht als POSIX -Shell -Skript arbeitet. Kurzer, nicht -Pox -Skripte wie CSH/TCSH können leicht eine "POSIX" -Syntax -Übereinstimmung auslösen. Beachten Sie auf jeden Fall, dass der Shebang erforderlich ist, um sicherzustellen, dass Ihre Skripte ordnungsgemäß interpretiert werden.
Beachten Sie, dass Funk möglicherweise keine Berechtigungswarnungen darstellt, wenn die Skripte auf Nicht-Unix-Dateisystemen wie NTFS untergebracht sind, bei denen häufig ausführbare Bits in den Dateimetadaten insgesamt fehlen. Stellen Sie beim Speichern von Shell -Skripten unbedingt die entsprechenden Dateiberechtigungen ein und übertragen Sie Dateien als Bündel in einem Tarball oder ähnlich wie bei der Schutzsicherung vor fallengelassenen Berechtigungen.
Beachten Sie, dass Funk vor Interpreter -Fehlanpassungen für Skripte mit fremden Punkten im Dateinamen warnen kann. Nennen Sie die sample.envrc .envrc.sample Nennen Sie die Datei wget-google-com anstelle von wget-google.com . Anhänge .sh ist ebenfalls eine Option, also update.es.cluster in update.es.cluster.sh .
Das optionale Flag -modulino zum Funk ermöglicht eine strenge Trennung von Skriptaufgaben in verschiedene Anwendungsskripte im Vergleich zu Bibliotheksskripten. Anwendungsskripte werden im hello ausgeführt, indem $PATH den Pfad aufrufen ~/bin/hello z ./hello Anwendungsskripte Feature -Eigentümer ausführbarer Berechtigungen sowie möglicherweise Gruppen und andere sowie andere Anforderungen an die Systemkonfiguration. Im Gegensatz dazu sollen Bibliothekskripte mit DOT ( . ) Oder source in Benutzerschalen oder andere Skripte importiert werden und sollten eine Dateierweiterung wie .lib.sh , .sh , .bash usw. Durch die Verwendung separater Benennungskonventionen vermitteln, kommunizieren wir schneller mit nachgeschalteten Benutzern, wie sie mit einem Shell -Skript interagieren. Insbesondere durch das Absetzen von Dateierweiterungen für Shell -Skriptanwendungen ermutigen wir die Autoren, aussagekräftigere Skriptnamen zu wählen. Wählen Sie anstelle des generischen build.sh build-docker . Anstelle von kafka.sh wählen Sie start-kafka , kafka-entrypoint usw.
Schließlich druckt stink einen Datensatz der Posixyness jeder Datei, einschließlich aller interessanten Felder, die auf dem Weg identifiziert wurden. Beachten Sie, dass einige Felder null bewerten können, wenn der Gestank von POSIX oder ROSY WAFT von NonpoSix überwältigend ist, kurzüberschreitende Analyse. Diese Kurzschlussfunktion beschleunigt dramatisch, wie stank große Projekte durchsucht.
Beachten Sie, dass die Berechtigungen aufgrund von Einschränkungen der JSON -Integer -Formatierung als Dezimalstellen weitergeleitet werden (wir wollten kein benutzerdefiniertes Octal String -Feld verwenden). Verwenden Sie echo 'obase=8;<some integer> | bc , um diese Werte in Oktal anzuzeigen.
Beachten Sie, dass Legacy-Systeme, Pakete und Shell-Skripte, die sich auf "SH" beziehen, auf eine Fülle von Pos-Pox-Shells verweisen können. Moderne Systeme benennen "sh" in "lksh", "tsh", "etsh" usw. um, um Verwirrung zu vermeiden. Im Allgemeinen wird die STANK-Suite davon ausgehen, dass die Mehrheit der gescannten Skripte auf die Technologie nach der 1971 abzielt. Verwenden Sie daher Ihre menschliche Intuition und Ihren Kontext, um jedes Legacy Thompson Unix V6 "SH" usw. zu notieren. Die meisten modernen Linter können solche Skripte weder in irgendeiner Komplexität analysieren, noch werden sie sie für die Legacy -Skripte erkennen, die sie sind, es sei denn, die Schriften der Skripte werden mit den modernen Retro -Dolmetschern "LKSH", "TSH", "ETSH" usw. für den Einsatz auf modernen Unix -Systemen gerendert. Man könnte die FS -Statistiken fast zur Änderung/Änderung verwenden, um diese Vermächtnisse auszusetzen, aber dies ist eine praktisch unrealistische Annahme, mit Ausnahme des zwangsten Archäologen, der fleißig sicherstellt, dass ihre Legacy -Skripte auch nach experimentellen Inhaltsmodifikationen weiterhin die Metadaten der 1970er Jahre präsentieren. Das Stank -System wird also einfach SH -> POSIX SH, KSH -> KSH88 / KSH93 für die Modernität und das Gleichgewicht annehmen.
In ähnlicher Weise präsentiert der alte Bourne Shell alias "Sh" alias "bsh" Schwierigkeiten mit Sprachidentifikationen. Old Bourne Shell Skripte präsentieren sich am wahrscheinlichsten mit "SH" Shebangs, was in Ordnung ist, da Bourne SH und KSH88/PDKSH/KSH als Basen für den POSIX SH -Standard dient. Einige moderne Systeme können eine Bourne -Shell als "SH" oder "BSH" -Binärdehäude präsentieren. Ersteres präsentiert nur wenige Probleme für die Identifizierung von Stank, obwohl "BSH" schwierig ist, da der Großteil seiner heutigen Verwendungen nicht mit der Bourne -Shell, sondern mit der Java Beanshell verbunden ist. Daher kann Stank standardmäßig bsh Skripte als Nicht-Posixy behandeln, und solche Bourne-Shell-Skripte werden empfohlen, entweder bash oder sh Shebangs und möglicherweise .sh oder .bash Erweiterungen zu besitzen, um sich selbst als moderne, possix konforme Skripte zu identifizieren.
$ stink examples/hello
{"Path":"examples/hello","Filename":"hello","Basename":"hello","Extension":"","Shebang":"#!/bin/sh","Interpreter":"sh","LineEnding":"n","FinalEOL":false,"ContainsCR":false
,"Permissions":509,"Directory":false,"OwnerExecutable":true,"BOM":false,"POSIXy":true,"AltShellScript":false}
$ stink -pp examples/hello
{
"Path": "examples/hello",
"Filename": "hello",
"Basename": "hello",
"Extension": "",
"Shebang": "#!/bin/sh",
"Interpreter": "sh",
"LineEnding": "n",
"FinalEOL": false,
"ContainsCR": false,
"Permissions": 509,
"Directory": false,
"OwnerExecutable": true,
"BOM": false,
"POSIXy": true,
"AltShellScript": false
}
$ stink -pp examples/hello.py
{
"Path": "examples/hello.py",
"Filename": "hello.py",
"Basename": "hello.py",
"Extension": ".py",
"Shebang": "#!/usr/bin/env python",
"Interpreter": "python",
"LineEnding": "n",
"FinalEOL": false,
"ContainsCR": false,
"Permissions": 420,
"Directory": false,
"OwnerExecutable": false,
"BOM": false,
"POSIXy": false,
"AltShellScript": false
}
$ stink -help
-cr
Report presence/absence of any CR/CRLF's
-eol
Report presence/absence of final end of line sequence
-help
Show usage information
-pp
Prettyprint smell records
-version
Show version information Die enthaltenen examples/ Verzeichnisse zeigen viele Randfälle, wie leere Skripte, skebanglose Skripte, erweiterte und erweiterte Skripte und verschiedene Hello World-Anwendungen in vielen Programmiersprachen. Einige Dateien, wie examples/goodbye können 100% gültiges POSIX-Shell-Skriptinhalt enthalten, sich jedoch nicht mit Shebangs oder relevanten Dateierweiterungen selbst identifizieren. In einem großen Projekt können solche Dateien fälschlicherweise als Whoknowswhat -Format oder einfach einfacher Text behandelt werden. Möglicherweise könnten statistische Methoden dazu beitragen, POSIX -Grammatiken zu identifizieren, aber selbst eine leere Datei ist technisch gesehen POSIX, was vom Standpunkt der Klassifizierung nicht hilfreich ist. In jedem Fall deckt examples/ hoffentlich die häufigeren Fälle von Rand ab.
Eine Möglichkeit, an stank zu denken, ist ein Kopfgeldjäger für Shell -Skripte.
Angesichts der Tatsache, dass Shell tendenziell zerbrechlicher ist als Programmiersprachen auf höherer Ebene, ist es eine gute Idee, Shell -Code als dedizierte Anwendungen neu zu schreiben. Go und Rost sind besonders gute Wahl für Anwendungssprachen.
Die Rust -Programmiersprache hat am besten in der Unterrichtsleistung, zuverlässig und in der Sicherheit. Die Go -Programmiersprache hat in den meisten Kontexten eine vergleichbare Leistung, Zuverlässigkeit und Sicherheit. Sowohl Rost als auch Go unterstützen die Cross-Compilation- und die statischen ausführbaren Ausführungen, sodass es im Vergleich zu schuppigen Shell-Skripten viel einfacher ist, Rost/GO-Anwendungen zu entwickeln, zu testen, zu packen und zu verteilen. Die meisten Shell -Codierer vernachlässigen es, subtile Verkäufer -Verriegelungsprobleme mit der Shell -Syntax und die für einzelne Befehle verwendeten Flags zu berücksichtigen. Rust hat eine steilere Lernkurve, als einige Codierer bereit sind, Zeit zu widmen. Oft kann Go als Kompromiss dienen. Zusammengenommene Sprachen, sowohl Rost als auch GO, sind vor vielen Laufzeiten geschützt, die Muscheln und andere interpretierte Sprachen einladen.
Unabhängig davon ist die jeweilige Programmiersprache weniger wichtig, sofern es sich nicht um Schale handelt. Notorisch gefährliche Programmiersprachen wie JavaScript und Perl sind immer noch sicherer als Shell. Shell (jedes Geschmack) ist ein Müllfeuer, das auf einen Funken wartet.
Glücklicherweise kann die Liste der Shell -Skripte, die stank ausgeben, Ingenieuren helfen, Programmkandidaten zu identifizieren, um in reiferen Programmiersprachen umzuschreiben.
BSD-2-Klausel
(Keiner)
Weitere Informationen zur Entwicklung von Stank selbst finden Sie unter Entwicklung.md.
Beachten Sie, dass sehr viele Softwarekomponenten eine schlechte Angewohnheit haben, eingebettete Inline-Shell-Skript-Schnipsel in Nicht-Schalen-Skriptdateien zu fördern. Zum Beispiel führen CI/CD -Jobkonfigurationen, Dockerfile -Schritte, Kubernetes -Ressourcen und machen Sie aus. Die meisten Linter -Tools (für Shell -Skripte und andere Sprachen) haben eine sehr begrenzte oder nicht vorhandene Unterstützung für das Linken von Inline -Shell -Skript -Snippets.
Verschieben Sie das Shell -Skript -Schnipsel in eine dedizierte Shell -Skriptdatei. Lassen Sie die Softwarekomponente dann das Shell -Skript ausführen. Anschließend können Sie den Shell -Code mit mehr Tools abgeben und dadurch das Qualitätsniveau Ihres Systems erhöhen.
Einige dunkle Dateien, wie der gemeinsame Lisp-Quellcode mit Multiline, Polyglot Shebangs und keine Dateierweiterung, können fälschlicherweise die Stank-Bibliothek auslösen, sowie die Stink- und Stank-Anwendungen, die in der ersten Zeile des Hacky Shebang kurzgeschlossen sind. Solche Dateien können fälschlicherweise als "POSIX" -Code identifiziert werden, was eigentlich das beabsichtigte Verhalten ist! Dies liegt daran, dass der Polyglot Shebang ein Hack ist, um Einschränkungen in der gemeinsamen LISP-Sprache zu erledigen, die normalerweise keine POSIX Shebang-Kommentare akzeptiert, um gemeinsame Lisp-Skripte in Bash zu senken. Für diese Situation ist es am besten, solchen Dateien eine ordnungsgemäße Dateierweiterung zu liefern.
$ head examples/i-should-have-an-extension
#!/usr/bin/env sh
#|
exec clisp -q -q $0 $0 ${1+"$@"}
|#
(defun hello-main (args)
(format t "Hello from main!~%"))
;;; With help from Francois-Rene Rideau
;;; http://tinyurl.com/cli-args
$ stink -pp examples/i-should-have-an-extension
{
"Path": "examples/i-should-have-an-extension",
"Filename": "i-should-have-an-extension",
"Basename": "i-should-have-an-extension",
"Extension": "",
"BOM": false,
"Shebang": "#!/usr/bin/env sh",
"Interpreter": "sh",
"LineEnding": "n",
"POSIXy": true
} Ankleben Sie möglicherweise eine .lisp -Erweiterung an solche Dateien. Oder trennen Sie das Modulino in die Befehlszeilenmodule für Clear Library vs. Oder extrahieren Sie die Shell -Interaktion in ein dediziertes Skript. Oder überzeugen Sie die Sprachbetreuer, Shebangs als Kommentare zu behandeln. Schreiben Sie Ihren Kongressabgeordneten. Wie auch immer Sie dies lösen, wissen, dass die aktuelle Situation weit außerhalb der Norm liegt und wahrscheinlich eine angemessen arkane und dramatische Weise brechen kann. Mit Wyverns und flammenden Meeren und Anschlüssen aller kranken Art.
Diese schlechten Bois helfen dabei, Ihre Shell -Skripte zu stützen. Obwohl sie so konzipiert sind, dass sie an einzelnen Dateien arbeiten, stellen Sie also unbedingt größere Projekte und leiten Sie die Ergebnisse in xargs [-0] [-n ... shellcheck .
ACK bietet Flaggen an, die ähnlich stank --shell [-f] , mit der Einschränkung, dass ACK in diesen Ergebnissen nicht-Pox-Muscheln wie CSH, TCSH und Fisch enthält. Zum jetzigen Zeitpunkt kann Possix -Shells wie Asche, Dash, Posh, PDKSH, KSH93 und MKSH nicht einbezogen werden. ACK hängt auch von Perl ab und macht es für Docker -Microservices und andere eingeschränkte Plattformen schwerer.
Kirill identifiziert JSON -Dokumente.
Linguist, Githubs außergewöhnliche Bemühungen, zu identifizieren, in welcher Sprache jede Millionen von Repositorys geschrieben sind. Während dieses stanky GO -Projekt keinen Linguisten in automatisierter Analyse einsetzt, ist es für forensische Zwecke erwähnenswert, wenn Sie jemals auf eine seltsame, nicht identifizierte (oder falsch identifizierte!) Quellcode -Datei stoßen.
Linters, ein Wiki gemeinsamer Programmiersprache und Sast -Tools.
Periscop warnt vor ungeschichteten NPM -Paketen.
Segel identifiziert C/C ++ Quellcode -Dateien.
Slick bietet sh -n -Syntax -Überprüfung gegen Pure Possix -Syntax an, während der tatsächliche sh auf den meisten Systemsymlinks zum Schlagen ist.
Unmake, ein Linter für Makefiles.