Stank는 Bash, SH, ZSH, KSH 등과 같은 쉘 스크립트를 Garbaggio의 펑키 한 농장 프레쉬 gobs와 같은 쉘 스크립트를 식별하기위한 파일을 스니핑하기위한 명령 줄 유틸리티의 라이브러리 및 모음입니다. RB, PY, PL과 같은 다른 더 맛있는 파일과 비교합니다.
믿거 나 말거나, 쉘 스크립트는 글을 잘 쓰는 것이 어렵 기 때문에 개발자가 더 안전한 언어로 쉘 스크립트를 작성하거나, 그렇지 않으면 스크립트를 Linters의 Armada와 함께 전쟁 게임하는 것입니다. 문제는 대규모 프로젝트에서 어떤 파일이 Dog Posix를 준수하는 쉘 스크립트에 정직하고 어떤 파일이 척하는지 확신 할 수 없다는 것입니다. CSH, TCSH, FISH, ION, RC 및 대부분의 기타 BASH의 비류는 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는 일부 유니 코드 스크립트에서 부적절한 라인 엔딩, 바이트 주문 마커의 존재와 같은 스크립트에서 나오는 이상한 냄새를보고합니다.
$ 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 스크립트와 같은 낮은 레벨의 비 포스 스크립트를 선택할 수 있습니다.
확장이 누락 된 경우 Funk는 Shebang을 잃어버린 것에 대해 안정적으로 경고 할 수 없습니다. 일반적으로 스크립트 저자는 하나 또는 다른 하나를 사용하여 파일을 쉘 스크립트로 표시합니다. Shebang과 파일 확장자가 모두 부족한 것은 파일에 많은 언어에 대한 코드가 포함되어있어 코드의 posixy 특성을 결정하기가 어렵다는 것을 의미합니다. 수십 개의 사용 가능한 쉘 언어에 걸쳐 구문 적 유효성에 대한 파일 내용을 테스트하기 위해 철저한 AST 세트가 적용 되더라도, 파일의 의도는 POSIX 쉘 스크립트로 작동하지는 않지만 내용이 부정 행위로 유효한 스크립트 구문 일뿐 만 아니라 더 짧은 파일에 강력한 가능성이 있습니다. CSH/TCSH와 같은 짧은 비 포스 스크립트는 "POSIX"구문 일치를 쉽게 트리거 할 수 있습니다. 어쨌든, Shebang은 스크립트를 올바르게 해석하도록하는 데 필수적이라는 것을 알고 있습니다.
스크립트가 NTFS와 같은 비 전구 파일 시스템에 보관되어있는 경우 Funk는 권한 경고를 제시하지 못할 수 있습니다. 쉘 스크립트를 저장할 때는 적절한 파일 권한을 설정하고 파일을 타르 볼에서 번들로 전송하거나 삭제 된 권한에 대한 보호를 위해 유사하게 파일을 전송하십시오.
Funk는 파일 이름에 외부 점이있는 스크립트에 대한 통역사 불일치에 대해 경고 할 수 있습니다. .envrc.sample 대신 파일 sample.envrc 의 이름을 지정하십시오. wget-google.com 대신 wget-google-com 파일의 이름을 지정하십시오. 첨부 .sh 는 옵션이므로 update.es.cluster Renames on update.es.cluster.sh .
선택적 -modulino Flag to Funk를 사용하면 스크립트 직무를 엄격하게 분리 할 수 있습니다. 애플리케이션 스크립트는 일반적으로 ./hello 또는 ~/bin/hello hello $PATH 경로를 호출하여 실행됩니다. 애플리케이션 스크립트에는 시스템 구성 요구에 따라 소유자 실행 가능 권한 및 그룹 및 기타가 포함됩니다. 대조적으로, 라이브러리 스크립트는 DOT ( . ) 또는 source 로 사용자 쉘 또는 기타 스크립트로 가져 오도록 의도되며, 별도의 이름 지정 규칙을 사용하여 .lib.sh , .sh , .bash 등과 같은 파일 확장자가 있어야합니다. 특히 쉘 스크립트 응용 프로그램에 대한 파일 확장자를 삭제하여 저자가보다 의미있는 스크립트 이름을 선택하도록 권장합니다. 일반적인 build.sh 대신 build-docker 선택하십시오. kafka.sh 대신 start-kafka , kafka-entrypoint 등을 선택하십시오.
마지막으로, stink 각 파일의 posixyness에 대한 레코드를 인쇄합니다. Posix의 악취 또는 Nonposix의 장미 빛 waft가 압도적이고 단락 된 분석 인 경우 일부 필드는 0의 가치가있을 수 있습니다. 이 단락 기능은 stank 대규모 프로젝트를 검색하는 방법을 크게 향상시킵니다.
JSON 정수 서식의 제약으로 인해 권한이 소수로 전달됩니다 (사용자 정의 Octal String 필드를 사용하고 싶지 않았습니다). echo 'obase=8;<some integer> | bc 사용하십시오 echo 'obase=8;<some integer> | bc 이들 값을 8 월에 표시합니다.
"SH"를 참조하는 레거시 시스템, 패키지 및 쉘 스크립트는 수많은 포스 쉘을 참조 할 수 있습니다. 현대 시스템은 "sh"로 "lksh", "tsh", "etsh"로 이름을 바꿉니다. 혼란을 피하기 위해. 일반적으로 Stank Suite는 스캔되는 대부분의 스크립트가 1971 년 이후 기술을 대상으로한다고 가정하므로 인간의 직관과 컨텍스트를 사용하여 레거시 Thompson v6 "sh"등을 주목하십시오. 스크립트. 대부분의 현대식 라이터는 현대의 UNIX 시스템에 배치 할 때 현대의 레트로 통역사 "LKSH", "TSH", "Etsh"등으로 스크립트의 셰블이 렌더링되지 않는 한, 복잡성의 그러한 스크립트를 구문 분석 할 수 없으며, 스크립트의 Shebangs가 현대적인 레트로 통역사 "Lksh", "Etsh"등으로 렌더링되지 않는 한 그것들을 인식하지 못할 것입니다. 이러한 유산 특이점을 식별하기 위해 수정/변경을 위해 FS 통계를 거의 사용할 수 있지만, 이것은 가장 강박적인 고고학자를 제외하고 실험적으로 비현실적인 가정이므로, 레거시 스크립트가 실험적인 내용 수정 후에도 1970 년대 메타 데이터를 부지런히 보장합니다. 따라서 Stank 시스템은 단순히 현대성과 균형을 위해 sh-> posix sh, ksh-> ksh88 / ksh93을 가정합니다.
마찬가지로, 오래된 Bourne Shell 일명 "Sh"일명 BSH "는 언어 식별 어려움을 제시합니다. Old Bourne Shell 스크립트는 Bourne SH와 KSH88/PDKSH/KSH가 POSIX SH 표준의 기초 역할을했기 때문에 "SH"SHEBANGS를 제시 할 가능성이 가장 높습니다. 일부 현대 시스템은 Bourne 쉘을 "SH"또는 "BSH"바이너리로 제시 할 수 있습니다. 전자는 Stank 식별에 대한 몇 가지 문제를 제시하지만 "BSH"는 까다 롭지는 않지만 오늘날의 사용의 대부분은 Bourne Shell과 관련이 없지만 Java Beanshell과 관련이 있기 때문입니다. 따라서 STANK는 bsh 스크립트를 비 포닉스로 처리하는 데 기본값이 될 수 있으며, 이러한 Bourne Shell 스크립트는 현대적이고 Posix 준수 스크립트로 자체 식별하기 위해 bash 또는 sh Shebangs 및 .SH 또는 .SH 또는 .sh 또는 .SH 또는 .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/ 디렉토리는 빈 스크립트, Shebang-Less 스크립트, 확장 및 확장이없는 스크립트 및 다양한 프로그래밍 언어의 다양한 Hello World 응용 프로그램과 같은 많은 엣지 케이스를 보여줍니다. examples/goodbye 와 같은 일부 파일에는 100% 유효한 POSIX 쉘 스크립트 콘텐츠가 포함될 수 있지만 Shebangs 또는 관련 파일 확장자로 자체 식별하지 못합니다. 대규모 프로젝트에서 이러한 파일은 실수로 Whoknowwhat 형식 또는 단순히 일반 텍스트로 취급 될 수 있습니다. 아마도 통계적 방법은 posix 문법을 식별하는 데 도움이 될 수 있지만, 빈 파일조차도 기술적으로 posix이며, 신뢰할 수있는 분류 관점에서 도움이되지 않습니다. 어쨌든 examples/ 더 일반적인 가장자리 사례를 다룹니다.
stank 생각하는 한 가지 방법은 쉘 스크립트를위한 현상금 사냥꾼입니다.
쉘이 고급 프로그래밍 언어보다 깨지기 쉬운 경향이 있기 때문에 쉘 코드를 전용 응용 프로그램으로 다시 작성하는 것이 좋습니다. Go and Rust는 특히 응용 프로그램 언어를위한 좋은 선택입니다.
Rust 프로그래밍 언어는 수업 성능, 신뢰성 및 보안에서 가장 좋습니다. GO 프로그래밍 언어는 대부분의 상황에서 비슷한 성능, 신뢰성 및 보안을 가지고 있습니다. Rust and Go는 크로스 컴파일 및 정적 실행 파일을 지원하므로 플라운 쉘 스크립트에 비해 Rust/Go 응용 프로그램을 개발, 테스트, 포장 및 배포하기가 훨씬 쉽습니다. 대부분의 쉘 코더는 쉘 구문 및 개별 명령에 사용되는 플래그의 미묘한 공급 업체 잠금 문제를 고려하지 않습니다. Rust는 일부 코더가 기꺼이 시간을 할애하는 것보다 가파른 학습 곡선을 가지고 있습니다. 종종 GO는 타협으로 작용할 수 있습니다. Rust와 Go는 편집 된 언어를 편집하는 것은 껍질과 다른 해석 된 언어가 초대하는 많은 런타임 함정으로부터 보호됩니다.
어쨌든, 특정 프로그래밍 언어는 쉘이 아닌 한 덜 중요하고 관심사입니다. JavaScript 및 Perl과 같은 악명 높은 위험한 프로그래밍 언어는 여전히 쉘보다 안전합니다. 쉘 (모든 맛)은 스파크를 기다리는 쓰레기 불입니다.
다행스럽게도, stank 방출하는 쉘 스크립트 목록은 엔지니어가 프로그램 후보자가보다 성숙한 프로그래밍 언어로 다시 작성하도록 식별하는 데 도움이 될 수 있습니다.
BSD-2-Clause
(없음)
Stank 자체 개발에 대한 자세한 내용은 Development.md를 참조하십시오.
매우 많은 소프트웨어 구성 요소는 내장 된 인라인 쉘 스크립트 스 니펫을 비 쉘 스크립트 파일에 장려하는 습관이 좋지 않습니다. 예를 들어, CI/CD 작업 구성, DockerFile Run 단계, Kubernetes 리소스 및 Make. 대부분의 Linter 도구 (쉘 스크립트 및 기타 언어의 경우)는 인라인 쉘 스크립트 스 니펫을 줄이는 데 매우 제한적이거나 존재하지 않습니다.
따라서 쉘 스크립트 스 니펫을 전용 쉘 스크립트 파일로 이동하십시오. 그런 다음 소프트웨어 구성 요소가 쉘 스크립트를 실행하도록하십시오. 그런 다음 더 많은 도구로 쉘 코드를 보풀로 채울 수있게하여 시스템의 품질 수준을 높일 수 있습니다.
멀티 린, 폴리 글로트 셰 잔 및 파일 확장 기능이없는 공통 LISP 소스 코드와 같은 일부 모호한 파일은 해킹 라이브러리를 거짓으로 트리거 할 수 있으며, 해킹 셰 잔의 첫 번째 줄에 단락을 일으키는 악취 및 스탠드 애플리케이션이 잘못 트리거 될 수 있습니다. 이러한 파일은 잘못된 행동 인 "posix"코드로 거짓으로 식별 될 수 있습니다! Polyglot Shebang은 일반적인 LISP 언어의 한계를 해결하기위한 해킹이기 때문에 일반적으로 Posix Shebang 주석을 받아들이지 않기 때문에 일반적인 LISP 스크립트를 bash에서 점점 hatsable 수 있습니다. 이 상황에서는 해당 파일에 적절한 파일 확장을 제공하는 것이 가장 좋습니다.
$ 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 확장을 추가하십시오. 또는 모듈 리노를 Clear 라이브러리 대 명령 줄 모듈로 분리하십시오. 또는 쉘 상호 작용을 전용 스크립트로 추출하십시오. 또는 언어 관리자가 Shebangs를 의견으로 취급하도록 설득하십시오. 하원 의원을 쓰십시오. 그러나 당신은 이것을 해결하고, 현재 상황이 표준을 훨씬 벗어나고, 적절하게 비교적이고 극적인 패션에 빠질 가능성이 높다는 것을 알고 있습니다. Wyverns와 Flaming Seas와 모든 악의적 인 방식으로.
이 나쁜 보이스는 당신의 쉘 스크립트를 초래하는 데 도움이됩니다. 개별 파일에서 작동하도록 설계되었지만 더 큰 프로젝트를 습격하고 결과를 xargs [-0] [-n ... shellcheck 에 파이프하십시오.
ACK를 제공합니다 --shell [-f] 플래그는 stank 와 유사하게 작동하며 ACK에는 CSH, TCSH 및 물고기와 같은 비 포스 쉘이 포함되어 있다는 경고가 있습니다. 그러나이 글을 쓰는 시점에는 Ash, Dash, Posh, PDKSH, KSH93 및 MKSH와 같은 Posix 쉘이 포함되지 않습니다. ACK는 또한 PERL에 의존하여 Docker 마이크로 서비스 및 기타 제한된 플랫폼에 대해 더 헤비급을 만듭니다.
Kirill은 JSON 문서를 식별합니다.
언어 학자 인 Github의 각 수백만 개의 리포지토리가 어떤 언어로 작성되는지 식별하려는 Github의 특별한 노력.이 끔찍한 Go 프로젝트는 자동화 된 분석에서 언어 학자를 사용하지 않지만, 이상하고 미확인 된 (또는 잘못 식별 된!) 소스 코드 파일을 발견 한 경우 법 의학적 목적으로 언급 할 가치가 있습니다.
Linters, 일반적인 프로그래밍 언어 라이터 및 Sast 도구의 위키.
Periscope는 노출되지 않은 NPM 패키지에 대해 경고합니다.
SAIL은 C/C ++ 소스 코드 파일을 식별합니다.
Slick은 순수한 posix 구문에 대해 sh -n 구문 확인을 제공하는 반면, 대부분의 시스템에서 실제 sh symlinks to bash를 제공합니다.
Makefiles를위한 린터.