Stankは、Sniftingファイル用のコマンドラインユーティリティのライブラリとコレクションであり、GarbaggioのファンキーなFarmfresh Gobsなど、Bash、SH、ZSH、KSHなどのシェルスクリプトを識別します。 RB、PY、PLなど、他のより味が良いファイル
信じられないかもしれませんが、シェルスクリプトはよく書くのが難しいことで有名です。そのため、開発者がより安全な言語でシェルスクリプトを書くか、リンターの艦隊でスクリプトをWargameにすることをお勧めします。トラブルは、大規模なプロジェクトでは、どのファイルがDog Posix準拠のシェルスクリプトに正直であり、どのファイルがプレゼントであるかをあまり確信できないことです。 CSH、TCSH、魚、イオン、RC、およびその他のバッシュの非デリバティブは、POSIX互換性がない傾向があります。これまでに続くのに十分なオタクであれば、いくつかのフルーティーな例でクラックラッキンを手に入れましょう!
Stankシステムには、Stank Goライブラリと、便利ないくつかのコマンドラインユーティリティが含まれています。 stank Applicationは、ソースコードの大規模なコレクションを覆うための便利なスタンドアロンフィルターとして設計された、POSIX由来のシェルスクリプトとそのパスを印刷するディレクトリとファイルをスキャンします。
$ cd examples
$ stank .
.profile
.shrc
.zlogin
... stank Command Lineユーティリティは、糸くずを保証する可能性のあるシェルスクリプトのファイルパスを検索します。
STANKは外部リナーと統合され、より大きなプロジェクトディレクトリ内で分析するために、より集中したファイルパスのセットを供給するのに役立ちます。
$ 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... git hook default *.sampleファイルを含むマシンで生成されたファイルは、自動的にスキップされます。
追加オプションについては、 stank -helpを参照してください。
https://github.com/mcandre/stank/releases
$ go install github.com/mcandre/stank/...@latesthttps://pkg.go.dev/github.com/mcandre/stank
funk Linterは、不適切な線の終わり、いくつかのUnicodeスクリプトにバイトオーダーマーカーの存在など、スクリプトから発せられる奇妙な臭いを報告します。
$ 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 stankとfunk両方に、FreeBSDで使用されるCSH/TCSHスクリプトなど、低レベルの非Posixスクリプトも選択できます。
拡張機能も欠落している場合、FunkはShebangsが欠落していることを確実に警告できないことに注意してください。通常、スクリプトの著者は、いずれかを使用して、ファイルをシェルスクリプトとしてマークします。シバンとファイル拡張機能の両方を欠いているということは、ファイルに多くの言語のコードが含まれているため、コードのポジーの性質を決定することが困難であることを意味します。 ASTの徹底的なセットが適用されていても、数十の利用可能なシェル言語で構文の妥当性をファイルコンテンツをテストしたとしても、コンテンツは単に偶発的に有効なスクリプト構文であるだけであるが、ファイルの意図はPOSIXシェルスクリプトとして動作することではないという強い可能性があります。 CSH/TCSHのような短い非Posixスクリプトは、「POSIX」構文の一致を簡単にトリガーできます。いずれにせよ、スクリプトが適切に解釈されるようにするために、シバンが必要であることを知ってください。
FUNKは、ファイルメタデータから完全に実行可能なビットがしばしば欠落しているNTFSなどの非UNIXファイルシステムにスクリプトが収容されている場合、権限の警告を提示できない場合があることに注意してください。シェルスクリプトを保存するときは、適切なファイルアクセス許可を設定し、ファイルをターボールまたは類似のバンドルとして、ドロップされたアクセス許可に対する保護と同様に転送してください。
Funkは、ファイル名に外部ドットを含むスクリプトの通訳の不一致を警告する場合があることに注意してください。 .envrc.sampleではなく、ファイルsample.envrcに名前を付けます。 wget-google.comではなく、ファイルwget-google-com名前を付けます。 Appling .shもオプションであるため、 update.es.cluster update.es.cluster.shに変更します。
Funkへのオプションの-modulinoフラグにより、スクリプトの義務を厳密に分離することができます。アプリケーションスクリプトは、通常./helloや~/bin/hello helloまたは$PATHが適切に変更された場合、パスを呼び出すことにより実行されます。アプリケーションスクリプトには、システム構成のニーズに応じて、所有者の実行可能アクセス許可、およびおそらくグループなども機能します。対照的に、ライブラリスクリプトは、ドット( . )またはsourceでユーザーシェルまたは他のスクリプトにインポートすることを目的としており.lib.sh 、 .sh 、 .bashなどのファイル拡張機能を備えている必要があります。特に、シェルスクリプトアプリケーションのファイル拡張子を削除することにより、著者がより意味のあるスクリプト名を選択することを奨励します。汎用build.shの代わりに、 build-dockerを選択します。 kafka.shの代わりに、 start-kafka 、 kafka-entrypointなどを選択してください。
最後に、 stink 、各ファイルのPosixynessのレコードを印刷します。これには、途中で特定した興味深いフィールドが含まれます。一部のフィールドは、Posixの悪臭またはNonposixのバラ色の波が圧倒的な短絡分析である場合、ゼロの評価である可能性があることに注意してください。この短絡機能により、 stank大規模なプロジェクトを検索する方法を劇的に高速化します。
JSON Integerフォーマットの制約により、アクセスは小数として中継されていることに注意してください(カスタムOctal Stringフィールドを使用したくありませんでした)。 echo 'obase=8;<some integer> | bcを使用しますこれらの値をOctalで表示するecho 'obase=8;<some integer> | bc 。
「sh」を参照するレガシーシステム、パッケージ、およびシェルスクリプトは、プレジックス前のシェルの多数を指す場合があることに注意してください。最新のシステムは、混乱を避けるために、「sh」を「lksh」、「tsh」、「etsh」などに変更します。一般に、Stank Suiteは、スキャンされているスクリプトの大部分が1971年以降のテクノロジーをターゲットにしていると想定しているため、人間の直観とコンテキストを使用して、Thompson Unix V6 "SH"などのレガシーに注意してください。ほとんどの最新のリナーは、そのようなスクリプトをいかなる複雑さも解析できず、現代のレトロな通訳者「LKSH」、「TSH」、「ETSH」などとスクリプトのシバンが現代のUNIXシステムに展開されるために、レガシースクリプトのためにそれらを認識することはできません。これらのレガシーの外れ値を特定するために、修正/変更にFS統計をほぼ使用できますが、これは、最も強迫観念的考古学者を除き、実質的に非現実的な仮定です。したがって、シュタンクシステムは、現代性とバランスのために、Sh-> posix sh、ksh-> ksh88 / ksh93を単純にパントして想定します。
同様に、古いボーンシェル別名「SH」別名「BSH」は、言語識別の困難を示しています。 Old Bourne Shell Scriptsは、Bourne SHとKSH88/PDKSH/KSHがPOSIX SH標準のベースとして機能したため、「SH」シバンを提示する可能性が最も高くなります。一部の最新のシステムは、「SH」または「BSH」バイナリとしてBourneシェルを提示する場合があります。前者は、「BSH」はボーンシェルではなく、Java Beanshellに関連しているため、「BSH」は扱いにくいものですが、症状の識別にはほとんど問題があります。したがって、STANKはbshスクリプトを非ポジーとして扱うことにデフォルトである可能性があり、そのようなBourneシェルスクリプトは、最新のPOSIX準拠のスクリプトとして自己識別するために、 bashまたはsh Shebangs、およびおそらく.shまたは.bash拡張機能のいずれかを特徴とすることをお勧めします。
$ 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含まれているexamples/ディレクトリは、空のスクリプト、シバンレススクリプト、拡張機能および拡張レススクリプト、多くのプログラミング言語にわたるさまざまなHello Worldアプリケーションなど、多くのエッジケースを示しています。 examples/goodbyeなどの一部のファイルには、100%有効なPOSIXシェルスクリプトコンテンツが含まれている場合がありますが、シバンまたは関連するファイル拡張子で自己識別できません。大規模なプロジェクトでは、そのようなファイルは、WhoknowSwhat形式、または単に単純なテキストとして誤って扱われる場合があります。おそらく統計的方法は、POSIXグラマーを特定するのに役立つ可能性がありますが、空のファイルでさえ技術的にはPOSIXであり、信頼できる分類の観点からは役に立たないものです。いずれにせよ、 examples/うまくいけば、より一般的なエッジのケースをカバーします。
stankを考える1つの方法は、シェルスクリプトの賞金稼ぎです。
シェルは、より高いレベルのプログラミング言語よりも脆弱である傾向があることを考えると、シェルコードを専用のアプリケーションとして書き換えることをお勧めします。行くと錆は、アプリケーション言語の特に良い選択です。
Rustプログラミング言語は、クラスのパフォーマンス、信頼性、セキュリティに最適です。 GOプログラミング言語には、ほとんどのコンテキストで同等のパフォーマンス、信頼性、セキュリティがあります。 RustとGoの両方の両方が、クロスコンパイルと静的実行可能ファイルをサポートするため、Flaky Shellスクリプトと比較してRust/Goアプリケーションの開発、テスト、パッケージ、および配布がはるかに簡単になります。ほとんどのシェルコーダーは、シェルの構文と個々のコマンドに使用されるフラグに関する問題の問題をロックする微妙なベンダーを検討することを怠っています。 Rustは、一部のコーダーが時間を費やす意思があるよりも急な学習曲線を持っています。多くの場合、GOは妥協として役立ちます。言語をまとめているため、錆びとgoの両方は、シェルや他の解釈言語が招待する多くのランタイムの落とし穴から保護されています。
とにかく、特定のプログラミング言語は、シェルではない限り、それほど重要ではなく、懸念事項です。 JavaScriptやPerlなどの危険なプログラミング言語は、シェルよりも安全です。シェル(任意のフレーバー)は、火花を待っているゴミ火です。
幸いなことに、 stankが放出するシェルスクリプトのリストは、エンジニアがより成熟したプログラミング言語で書き直すためにプログラム候補を特定するのに役立ちます。
BSD-2-Clause
(なし)
Stank自体の開発の詳細については、development.mdを参照してください。
非常に多くのソフトウェアコンポーネントには、埋め込まれたインラインシェルスクリプトスニペットを非シェルスクリプトファイルに奨励するという悪い習慣があることに注意してください。たとえば、CI/CDジョブ構成、DockerFileの実行ステップ、Kubernetesリソース、および作成。ほとんどのリンジターツール(シェルスクリプトやその他の言語用)は、糸くずのインラインシェルスクリプトスニペットを非常に限られている、または存在しないサポートを持っています。
したがって、シェルスクリプトスニペットを専用のシェルスクリプトファイルに移動します。そして、ソフトウェアコンポーネントにシェルスクリプトを実行させます。その後、シェルコードをより多くのツールで並べて、システムの品質レベルを上げることができます。
マルチラインを備えた一般的なLISPソースコード、ポリグロットシバン、およびファイル拡張機能なしなど、いくつかのかなりあいまいなファイルは、ハッキーシェバンの最初の行に短絡するスティンクライブラリ、およびスティンクおよびスティンクアプリケーションを誤ってトリガーする可能性があります。このようなファイルは、「POSIX」コードとして誤って識別される場合があります。これは、実際には意図した動作です!これは、ポリグロットシバンが、一般的なLISPスクリプトをBashでドットスラッシャブルにするために、通常、Posix Shebangコメントを受け入れない一般的なLisp言語の制限を回避するためのハックであるためです。この状況では、そのようなファイルに適切なファイル拡張機能を提供することが最善です。
$ 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
}おそらく、そのようなファイルに.lisp拡張機能を追加します。または、モジュリノをクリアライブラリ対コマンドラインモジュールに分離します。または、シェル相互作用を専用のスクリプトに抽出します。または、言語メンテナーにシバンをコメントとして扱うよう説得します。下院議員を書いてください。しかし、これを解決し、現在の状況が標準の範囲外であり、適切に不可解で劇的な方法で壊れる可能性が高いことを知ってください。ワイバーンと燃える海とあらゆる悪さの前兆があります。
これらの悪いボアは、シェルスクリプトを補強するのに役立ちます。それらは個々のファイルで動作するように設計されていますが、大規模なプロジェクトを汚し、結果をxargs [-0] [-n ... shellcheckにパイプするようにしてください。
ACKは、これらの結果にACKにCSH、TCSH、魚などの非Posixシェルが含まれるという警告を使用して、 stankと同様に機能する--shell [-f]フラグを提供します。しかし、この執筆時点では、Ash、Dash、Posh、Pdksh、KSH93、MKSHなどのPosixシェルが含まれていません。 ACKはPERLにも依存しているため、Dockerマイクロサービスやその他の制約付きプラットフォームによりヘビー級が増えています。
キリルはJSON文書を特定します。
言語学者は、何百万ものリポジトリが書かれている言語を特定するためのGithubの並外れた努力です。このStanky Goプロジェクトは、自動化された分析で言語学者を採用していませんが、奇妙で統一された(または誤認された!)ソースコードファイルに出くわした場合、法医学的な目的で言及する価値があります。
リナーは、一般的なプログラミング言語リナーとSASTツールのWikiです。
Periscopeは、非表示のNPMパッケージで警告しています。
SAILはC/C ++ソースコードファイルを識別します。
Slickは、純粋なPOSIXの構文に対してsh -n構文のチェックを提供しますが、ほとんどのシステムの実際のsh BASHにシンプルになります。
メイクファイルのリナーであるアンメイク。