Stank - это библиотека и коллекция утилит командной строки для обнюхивания файлов, чтобы идентифицировать сценарии оболочки, такие как Bash, SH, ZSH, KSH и т. Д. по сравнению с другими более вкусными файлами, такими как RB, PY, PL.
Хотите верьте, хотите нет, но сценариев оболочки сложно хорошо писать, поэтому разработчику следует писать сценарии оболочки на более безопасных языках, либо войти в свои сценарии с помощью армады Линтеров. Проблема заключается в том, что в крупных проектах никогда нельзя быть слишком уверенным, какие файлы честны для сценариев Socix, соответствующих Dog Posix, а какие - претенденты. CSH, TCSH, FISH, ION, RC и большинство других неработающих BASH, как правило, не совместимы с POSIX. Если вы достаточно отвратительны, чтобы следовать за этим, давайте возьмем Crackalackin с некоторыми фруктовыми примерами, черт возьми!
Система Stank включает в себя библиотеку Stank Go, а также несколько утилит командной строки для удобства. Сканирование приложений stank сканирует и файлы для сценариев оболочки, полученных из POSIX, и печатает их пути, разработанные как удобный автономный фильтр для сбора больших коллекций исходного кода.
$ cd examples
$ stank .
.profile
.shrc
.zlogin
... Утилита командной строки stank ищет пути файлов для сценариев оболочки, которые могут оправдать лининг.
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 *.sample Files, автоматически пропускаются.
Смотрите 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 имеют возможность выбирать и низкоуровневые, непосиксные сценарии, такие как сценарии CSH/TCSH, используемые в FreeBSD.
Обратите внимание, что Funk не может надежно предупредить о пропущенных шебанге, если расширение также отсутствует; Как правило, авторы сценариев используют один или другой для маркировки файлов в виде сценариев оболочки. Отсутствие как A, так и расширения файла, означает, что файл может содержать код для многих языков, что затрудняет определение посадочного характера кода. Даже если исчерпывающий набор AST применяется для проверки содержания файла на синтаксическую достоверность в десятках доступных языков оболочки, в более коротких файлах существует большая вероятность того, что содержимое является просто случайным синтаксисом скрипта, хотя намерение файла не состоит в том, чтобы работать в качестве сценария оболочки SEPIX. Короткие, непосиксные сценарии, такие как для CSH/TCSH, могут легко запустить синтаксис -матч «POSIX». В любом случае знайте, что шебанг необходим для обеспечения должным образом ваших сценариев.
Обратите внимание, что Funk может не представить предупреждения о разрешениях, если сценарии размещены в не-UNIX-файловых системах, таких как NTFS, где выполняемые биты часто отсутствуют в метаданных файлах вообще. При хранении сценариев оболочки обязательно установите соответствующие разрешения на файлы и перенесите файлы в виде пакета в тарболе или аналогичны защите от отброшенных разрешений.
Обратите внимание, что Funk может предупредить о несоответствиях интерпретатора для сценариев с посторонними точками в имени файла. А не .envrc.sample , назовите sample.envrc файла. Вместо wget-google.com назовите файл wget-google-com . Приложение .sh также является опцией, поэтому update.es.cluster re rearrame до update.es.cluster.sh .
Необязательный флаг -modulino для фанка позволяет строгое разделение обязанностей сценариев в различные сценарии применения против библиотечных сценариев. Сценарии приложений обычно выполняются путем вызова пути, например ./hello или ~/bin/hello или просто hello , когда $PATH соответственно изменен. Прикладные сценарии функционируют исполняемые разрешения владельца, а также, возможно, групповые и другие, а также в зависимости от потребностей в конфигурации системы. Напротив, библиотечные сценарии предназначены для импорта с помощью Dot ( . ) Или source в оболочки пользователей или другие сценарии, и должны иметь расширение файла, например .lib.sh , .sh , .bash и т. Д. Используя отдельные соглашения о именовании, мы быстрее общаемся с нисходящими пользователями, как взаимодействовать со сценарием оболочки. В частности, отбросив расширения файлов для приложений сценариев оболочки, мы рекомендуем авторам выбрать более значимые имена скриптов. Вместо общей build.sh выберите build-docker . Вместо kafka.sh выберите start-kafka , kafka-entrypoint и т. Д.
Наконец, stink печатает запись о посыпеле каждого файла, в том числе любые интересные поля, которые он идентифицировал по пути. Обратите внимание, что некоторые поля могут быть нулевыми оценками, если зловоние Posix или Rosy Waft of Ofposix является ошеломляющим, коротким замыкающим анализом. Этот короткий кружок показывает, как stank больших проектах ищет большие проекты.
Обратите внимание, что разрешения передаются в виде десятичных десятиц из -за ограничений на целочисленное форматирование JSON (мы не хотели использовать пользовательское восьмидесятническое поле). Используйте echo 'obase=8;<some integer> | bc , чтобы отобразить эти значения в восьмиуровне.
Обратите внимание, что устаревшие системы, пакеты и сценарии оболочки, ссылаясь на «SH», могут относиться к множеству раковинов Pre-Posix. Современные системы переименованы в «SH» в «LKSH», «TSH», «ETSH» и т. Д., Чтобы избежать путаницы. В целом, набор Stank предполагает, что большинство сканирующихся сценариев нацелены на технологию после 1971 года, поэтому используйте свою человеческую интуицию и контекст, чтобы отметить любые сценарии Legacy Thompson Unix V6 «SH» и т. Д. Большинство современных линтеров не смогут проанализировать такие сценарии какой -либо сложности, и они не признают их за унаследованные сценарии, которые они представляют, если только Шебангы сценариев не отображаются с современными ретро -переводчиками «LKSH», «TSH», «Etsh» и т. Д. Для развертывания в современных системах Unix. Можно почти использовать статистику FS для модификации/изменений, чтобы попытаться определить эти устаревшие выбросы, но это практически нереалистичное предположение, за исключением наиболее одержимого археолога, усердно обеспечивая, чтобы их устаревшие сценарии продолжали представлять метаданные 1970 -х годов даже после экспериментальных модификаций содержания. Таким образом, система охраны будет просто набивать и предполагать, что SH -> Posix SH, KSH -> KSH88 / KSH93 ради современности и баланса.
Точно так же старая раковина Bourne Aka "SH" AKA "BSH" представляет трудности с идентификацией языка. Старые сценарии Shell Bourne, скорее всего, будут представлять себя «Sh» Шебангами, которые в порядке, так как Bourne SH и KSH88/PDKSH/KSH служили основаниями для стандарта POSIX SH. Некоторые современные системы могут представлять оболочку Bourne как бинар «Sh» или «BSH». Первые представляют несколько проблем для идентификации вон, хотя «BSH» сложно, так как большинство его применений сегодня не связано не с Shell Bourne, а с Java Beanshell. Таким образом, Stank может по умолчанию, чтобы рассматривать сценарии bsh как непосиксированные, и любые такие сценарии Bourne Shell рекомендуются иметь либо bash , либо sh Shebangs, и, возможно .sh или .bash Extensions, чтобы самоидентифицировать себя как современные, соответствующие Posix сценарии.
$ 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 Shell, но не могут самоидентифицировать себя ни с Shebangs, ни с соответствующими расширениями файлов. В большом проекте такие файлы могут быть ошибочно рассматриваться как формат Whoknowswhat или просто простой текст. Возможно, статистические методы могут помочь идентифицировать грамматики POSIX, но даже пустой файл технически является POSIX, который бесполезен с надежной точки зрения классификации. В любом случае, examples/ надеюсь, охватывают более распространенные края.
Один из способов придумать о stank - охотник за головами для сценариев снаряда.
Учитывая, что Shell имеет тенденцию быть более хрупкой, чем языки программирования более высокого уровня, то это хорошая идея переписать код оболочки в качестве специальных приложений. Go и Rust - это особенно хороший выбор для языков применения.
Язык программирования ржавчины лучше всего в классе, надежности и безопасности. Язык программирования GO имеет сопоставимую производительность, надежность и безопасность в большинстве контекстов. Как ржавчина, так и go поддерживают кросс-компиляцию, так и статические исполняемые файлы, так что гораздо проще разработать, тестировать, упаковывать и распространять приложения Rust/Go по сравнению с сценариями. Большинство кодировщиков оболочки пренебрегают рассматривать тонкие задачи блокировки поставщиков с синтаксисом оболочки и флагами, используемыми для отдельных команд. У Rust есть более крутая кривая обучения, чем некоторые кодировщики готовы посвятить время. Часто GO может служить компромиссом. Будучи скомпилированными языками, как ржавчинами, так и GO защищены от многих ловушек во время выполнения, которые приглашают раковины и другие интерпретируемые языки.
Несмотря на это, конкретный язык программирования является менее важной, озабоченной, если он не оболочка. Общеизвестно опасные языки программирования, такие как JavaScript и Perl, все еще более безопасны, чем Shell. Оболочка (любой вкус) - это огонь, ожидающий искры.
К счастью, список сценариев оболочки, которые stank , может помочь инженерам идентифицировать кандидатов на программу для переписывания на более зрелых языках программирования.
BSD-2-CLAUSE
(Никто)
Для получения более подробной информации о самой разработке Stank см. Development.md.
Обратите внимание, что очень много компонентов программного обеспечения имеют плохую привычку поощрять встроенные встроенные фрагменты сценариев оболочки в файлы сценария без оболочки. Например, конфигурации задания CI/CD, DockerFile Run Steps, ресурсы Kubernetes и создание. Большинство инструментов Linter (для сценариев оболочки и других языков) имеют очень ограниченную или не существующую поддержку для встроенных сценариев сценариев Linting.
Соответственно, переместите фрагменты сценариев оболочки в выделенный файл скрипта оболочки. А затем попросите программного компонента выполнить скрипт оболочки. Тогда вы сможете оборвать код оболочки с большим количеством инструментов и тем самым повысить уровень качества вашей системы.
Некоторые довольно неясные файлы, такие как обычный исходный код LISP с многослойным, полиглот-шейбангс и отсутствие расширения файлов, могут ложно запустить библиотеку вонзащика, а также приложения вонючий и вооружение, которые коротко замыкают на первой строке Hacky Shebang. Такие файлы могут быть ложно идентифицированы как код «posix», который на самом деле является предполагаемым поведением! Это связано с тем, что полиглот Шебанг-это хакер для оборудования ограничений на языке общего LISP, который обычно не принимает комментарии Posix Shebang, чтобы получить общие сценарии LISP, чтобы быть точечными в Bash. Для этой ситуации лучше всего предоставить правильное расширение файла в такие файлы.
$ 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 к таким файлам. Или разделить модулино на четкую библиотеку и модули командной строки. Или извлечь взаимодействие оболочки в выделенный сценарий. Или убедить, что языковые активисты относились к Шебангсу как к комментариям. Напишите своего конгрессмена. Как бы вы решили это, знайте, что нынешняя ситуация далеко за пределами нормы и, вероятно, сломается соответственно и драматичным образом. С Wyverns и пылающими морями и предзнаменованиями всех больных манеров.
Эти плохие буины помогают укрепить сценарии корзины. Несмотря на то, что они предназначены для работы над отдельными файлами, поэтому обязательно заслуживаете более крупных проектов и приведите результаты к xargs [-0] [-n ... shellcheck .
ACK предлагает --shell [-f] флаги, которые действуют аналогично stank , с предостережением, что ACK включает в себя непозиксные раковины, такие как CSH, TCSH и FISH в этих результатах; Но на момент написания этой статьи не включает в себя раковины Posix, такие как Ash, Dash, Posh, PDKSH, KSH93 и MKSH. ACK также зависит от Perl, что делает его более тяжелым для микросервисов Docker и других ограниченных платформ.
Кирилл идентифицирует документы JSON.
Лингвист, необычайные усилия Github по определению того, в каком языке написаны каждый из миллионов хранилищ. Хотя этот проект GO не использует лингвист в автоматическом анализе, стоит упомянуть в судебных целях, если вы когда -либо сталкивались с странным, неопознанным (или неправильно идентифицированным!) Файл исходного кода.
Линтерс, вики с общими языками программирования и инструментами.
Periscope предупреждает о не затопленных пакетах NPM.
SAIL идентифицирует файлы исходного кода C/C ++.
Slick предлагает проверку синтаксиса sh -n на Pure POSIX, тогда как фактический sh на большинстве систем символизирует для удара.
Помекнуть, Линтер для Makefiles.