Stank é uma biblioteca e coleta de utilitários de linhas de comando para cheirar arquivos para identificar scripts de shell como Bash, Sh, Zsh, Ksh e assim por diante, aqueles gabares de Garbaggio. contra outros arquivos mais palatáveis, como RB, PY, pl.
Acredite ou não, os scripts de shell são notoriamente difíceis de escrever bem; portanto, é necessário um desenvolvedor escrever scripts de shell em idiomas mais seguros, ou então Wargame seus scripts com uma armada de linhagens. O problema é que, em grandes projetos, nunca se pode ter certeza de quais arquivos são honestos para os scripts de shell compatíveis com Posix e quais são pretendentes. CSH, TCSH, FISH, ION, RC e a maioria dos outros não -derivados de Bash tendem a não ser compatíveis com Posix. Se você é nerd o suficiente para ter seguido até agora, vamos ficar Crackalackin com alguns exemplos frutados, caramba!
O sistema fedado inclui a biblioteca GO, bem como vários utilitários de linha de comando por conveniência. O aplicativo stank verifica diretórios e arquivos para scripts de shell derivados de POSIX e imprime seus caminhos, projetados como um filtro independente conveniente para revestir grandes coleções de código-fonte.
$ cd examples
$ stank .
.profile
.shrc
.zlogin
... A linha de comando stank utilidade pesquisa caminhos de arquivo para scripts de shell que podem justificar o linhagem.
Stank integra -se a linters externos, ajudando a alimentá -los um conjunto mais focado de caminhos de arquivo para analisar em diretórios de projeto maiores.
$ 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... Os arquivos gerados por máquina, incluindo os arquivos do Git Hook Padrão *.sample , são ignorados automaticamente.
Consulte stank -help para opções adicionais.
https://github.com/mcandre/stank/releases
$ go install github.com/mcandre/stank/...@latesthttps://pkg.go.dev/github.com/mcandre/stank
O Linter funk relata odores estranhos que emanam de scripts, como terminações inadequadas de linha, a presença de marcadores de pedidos de bytes em alguns scripts 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 e funk também têm a capacidade de selecionar scripts de baixo nível e não -Posix, como scripts CSH/TCSH usados no FreeBSD.
Observe que o Funk não pode alertar de maneira confiável por perder shebangs se a extensão também estiver faltando; Normalmente, os autores do script usam um ou outro para marcar arquivos como scripts de shell. Na falta de uma extensão de shebang e de um arquivo, significa que um arquivo pode conter código para muitos idiomas, dificultando a determinação da natureza do Posixy do código. Mesmo que um conjunto exaustivo de ASTs seja aplicado para testar o conteúdo do arquivo quanto à validade sintática nos dezenas de idiomas disponíveis, existe uma forte possibilidade em arquivos mais curtos de que o conteúdo é apenas uma sintaxe de script válida incidentalmente, embora a intenção do arquivo não seja operar como um script de shell POSIX. Scripts curtos e não -posix, como para CSH/TCSH, podem facilmente desencadear uma correspondência de sintaxe "Posix". De qualquer forma, saiba que o shebang é necessário para garantir que seus scripts sejam devidamente interpretados.
Observe que o Funk pode deixar de apresentar avisos de permissões se os scripts estiverem alojados em sistemas de arquivos não unix, como NTFs, onde bits executáveis geralmente estão ausentes nos metadados do arquivo. Ao armazenar scripts de shell, certifique -se de definir as permissões de arquivo apropriadas e transferir arquivos como um pacote em um tarball ou semelhante para proteger as permissões caídas.
Observe que o Funk pode alertar sobre as incompatibilidades de intérpretes para scripts com pontos estranhos no nome do arquivo. Em vez de .envrc.sample , nomeie a sample.envrc de arquivo.envrc. Em vez de wget-google.com , nomeie o arquivo wget-google-com . Appender .sh também é uma opção, então update.es.cluster renomeia para update.es.cluster.sh .
O sinalizador opcional -modulino para o funk permite a separação estrita das tarefas de script, em scripts de aplicativos distintos vs. scripts da biblioteca. Os scripts do aplicativo são geralmente executados invocando o caminho, como ./hello ou ~/bin/hello ou simplesmente hello quando $PATH for modificado adequadamente. Os scripts de aplicativos apresentam permissões executáveis do proprietário e talvez o grupo e outros também, dependendo das necessidades de configuração do sistema. Por outro lado, os scripts da biblioteca devem ser importados com o DOT ( . ) Ou source em conchas de usuários ou outros scripts e devem apresentar uma extensão de arquivo como .lib.sh , .sh , .bash , etc. Ao usar convenções de nomeação separadas, nos comunicamos mais rapidamente aos usuários awnstream como interagir com um script. Em particular, ao soltar extensões de arquivo para aplicativos de script de shell, incentivamos os autores a escolher nomes de scripts mais significativos. Em vez da build.sh genérica.sh, escolha build-docker . Em vez de kafka.sh , escolha start-kafka , kafka-entrypoint , etc.
Finalmente, stink imprime um registro da posixyness de cada arquivo, incluindo os campos interessantes que identificou ao longo do caminho. Observe que alguns campos podem ser valorizados se o fedor de Posix ou Rosy Waft de Non-Posix for uma análise esmagadora e de curto-circuito. Esse recurso de curto-circuito acelera drasticamente como stank pesquisas de grandes projetos.
Observe que as permissões são transmitidas como decimais, devido a restrições na formatação inteira JSON (não queríamos usar um campo de sequência octal personalizado). Use echo 'obase=8;<some integer> | bc para exibir esses valores em octal.
Observe que os sistemas, pacotes e scripts de shell, referenciando "sh", podem se referir a uma infinidade de conchas pré-posix. Os sistemas modernos renomearam "sh" para "lksh", "tsh", "etsh", etc. para evitar confusão. Em geral, a suíte fedida assumirá que a maioria dos scripts que está sendo digitalizada está visando a tecnologia pós-1971; portanto, use sua intuição e contexto humano para observar qualquer legado Thompson Unix V6 "SH", etc. Scripts. A maioria dos linters modernos não será capaz de analisar tais scripts de qualquer complexidade, nem os reconhecerá pelos scripts herdados que são, a menos que os scripts dos scripts sejam apresentados com os modernos intérpretes "LKSH", "TSH", "etsh", etc., para implantar os sistemas unix modernos. É possível usar quase as estatísticas do FS para modificação/alteração para tentar identificar esses outliers legais, mas essa é uma suposição praticamente irrealista, exceto o arqueólogo mais obsessivo, garantindo diligentemente seus scripts legados continuando a apresentar metadados da década de 1970, mesmo após modificações experimentais de conteúdo. Portanto, o sistema fedado simplesmente afastará e assumirá sh -> posix sh, ksh -> ksh88 / ksh93 por uma questão de modernidade e equilíbrio.
Da mesma forma, o antigo Bourne Shell, também conhecido como "SH", também conhecido como "BSH", apresenta dificuldades de identificação de idiomas. Os antigos scripts de shell de Bourne provavelmente se apresentarão com Shebangs "SH", o que é bom como Bourne SH e Ksh88/PDKSH/KSH serviram como bases para o padrão Posix Sh. Alguns sistemas modernos podem apresentar uma concha Bourne como um binário "sh" ou "bsh". O primeiro apresenta poucos problemas para a identificação fedida, embora "BSH" seja complicado, pois a maioria de seus usos hoje não está associada à concha de Bourne, mas ao Java Beanshell. Portanto, o Stank pode padrão tratar os scripts bsh como não-pósxia, e esses scripts de shell de Bourne são aconselhados a apresentar shebangs bash ou sh , e talvez extensões .sh ou .bash , a fim de se identificar como roteiros modernos e compatíveis com 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 Os examples/ diretórios incluídos demonstram muitos casos de borda, como scripts vazios, scripts sem shebang, scripts extensos e sem extensão e várias aplicações do Hello World em muitas linguagens de programação. Alguns arquivos, como examples/goodbye podem conter 100% conteúdo de script de shell POSIX 100% válido, mas não conseguem se identificar com shebangs ou extensões de arquivo relevantes. Em um grande projeto, esses arquivos podem ser tratados por engano como formato whoknowswhat, ou simplesmente texto simples. Talvez os métodos estatísticos possam ajudar a identificar as gramáticas POSIX, mas mesmo um arquivo vazio é tecnicamente POSIX, o que é inútil do ponto de vista de classificação confiável. De qualquer forma, examples/ esperançosamente abrange os casos de borda mais comuns.
Uma maneira de pensar em stank é um caçador de recompensas para scripts de conchas.
Dado que o shell tende a ser mais frágil do que as linguagens de programação de nível superior, é uma boa idéia reescrever o código do shell como aplicativos dedicados. GO AND RUST são especialmente boas opções para idiomas de aplicação.
A linguagem de programação de ferrugem tem melhor desempenho, confiabilidade e segurança. A linguagem de programação GO tem desempenho, confiabilidade e segurança comparáveis na maioria dos contextos. Tanto o Rust quanto o Go suporta a compilação cruzada e os executáveis estáticos, para que seja muito mais fácil de desenvolver, testar, embalar e distribuir aplicativos Rust/Go em comparação com scripts de shell escamosos. A maioria dos codificadores de concha deixa de considerar problemas sutis de bloqueio de fornecedores com a sintaxe do shell e os sinalizadores usados para comandos individuais. Rust tem uma curva de aprendizado mais acentuada do que alguns codificadores estão dispostos a dedicar tempo. Muitas vezes, Go pode servir como um compromisso. Sendo idiomas compilados, tanto a ferrugem quanto a Go estão protegidos de muitas armadilhas de tempo de execução que conchas e outros idiomas interpretados convidam.
Independentemente disso, a linguagem de programação específica é uma preocupação menos importante, desde que não seja shell. Notoriamente, linguagens de programação perigosas, como JavaScript e Perl, ainda são mais seguras que a concha. Shell (qualquer sabor) é um fogo de lixo esperando por uma faísca.
Felizmente, a lista de scripts de shell que stank emite pode ajudar os engenheiros a identificar os candidatos ao programa para reescrever em linguagens de programação mais maduras.
BSD-2-cláusula
(Nenhum)
Para obter mais detalhes sobre o desenvolvimento do próprio Stank, consulte Development.md.
Observe que muitos componentes de software têm o mau hábito de incentivar trechos de script de shell incorporados e embutidos em arquivos de script que não são de casca. Por exemplo, configurações de trabalho de CI/CD, etapas do DockerFile Run, Kubernetes Recursos e Make. A maioria das ferramentas do Linter (para scripts de shell e outros idiomas) possui suporte muito limitado ou inexistente para liners scripts em linha de shell.
Consequentemente, mova os trechos de script do shell para um arquivo de script de shell dedicado. E depois que o componente de software execute o script do shell. Em seguida, você poderá fingir o código do shell com mais ferramentas e, assim, aumentar o nível de qualidade do seu sistema.
Alguns arquivos bastante obscuros, como o código-fonte LISP comum com multilina, shebangs de poliglota e nenhuma extensão de arquivo, podem acionar falsamente a biblioteca fedida e os aplicativos fedorentos e falhas, que curto-circuito na primeira linha do hacky shebang. Esses arquivos podem ser falsamente identificados como código "POSIX", que é realmente o comportamento pretendido! Isso ocorre porque o shebang poligloto é um hack para trabalhar em torno de limitações na linguagem Lisp comum, que normalmente não aceita comentários de Posix Shebang, a fim de que os scripts comuns do Lisp sejam derramáveis no Bash. Para esta situação, é melhor fornecer uma extensão de arquivo adequada a esses arquivos.
$ 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
} Talvez anexar uma extensão .lisp a esses arquivos. Ou separe o modulino em módulos de linha de comando clara vs. comando. Ou extraia a interação da concha para um script dedicado. Ou convencer os mantenedores de idiomas a tratar Shebangs como comentários. Escreva seu congressista. No entanto, você resolve isso, saiba que a situação atual está longe da norma e provavelmente quebrará de maneira adequadamente misteriosa e dramática. Com Wyverns e mares flamejantes e portentos de toda a maneira doente.
Esses bois ruins ajudam a sustentar seus scripts de shell. Embora eles sejam projetados para funcionar em arquivos individuais, portanto, certifique-se de falhar projetos maiores e colocar os resultados para xargs [-0] [-n ... shellcheck .
O ACK oferece sinalizadores --shell [-f] que agem de maneira semelhante a stank , com a ressalva de que o ACK inclui conchas não-posixes como CSH, TCSH e peixe nesses resultados; Mas até o momento em que este escrito falha em incluir conchas POSIX como Ash, Dash, Posh, PDKSH, KSH93 e MKSH. A ACK também depende do Perl, tornando -o mais pesado para microsserviços do docker e outras plataformas restritas.
Kirill identifica documentos JSON.
O linguista, o extraordinário esforço do Github para identificar em qual idioma cada um de seus milhões de repositórios está escrito. Embora esse projeto fedido de Go não empregue lingüista em análise automatizada, vale a pena mencionar para fins forenses, se você se deparar com um arquivo de código -fonte estranho, não identificado (ou equivocado!).
Linters, um wiki de linters de linguagem de programação comuns e ferramentas SAST.
O Periscope alerta em pacotes NPM não escondidos.
O Sail identifica arquivos de código -fonte C/C ++.
O Slick oferece verificação de sintaxe sh -n contra a sintaxe pura do POSIX, enquanto sh real na maioria dos sistemas links para bater.
Desmonte, um linhador para makefiles.