Stank adalah perpustakaan dan kumpulan utilitas baris perintah untuk mengendus file untuk mengidentifikasi skrip shell seperti bash, sh, zsh, ksh dan sebagainya, genangan funky farmfresh dari garbaggio; versus file lain yang lebih enak lainnya seperti RB, PY, PL.
Percaya atau tidak, skrip shell terkenal sulit untuk ditulis dengan baik, jadi perlu pengembang untuk menulis skrip shell dalam bahasa yang lebih aman, atau wargame skrip Anda dengan armada linter. Masalahnya adalah, dalam proyek besar orang tidak akan pernah terlalu yakin file mana yang jujur pada skrip shell yang sesuai dengan anjing, dan mana yang berpura -pura. CSH, TCSH, FISH, ION, RC, dan sebagian besar nonderi lainnya dari Bash cenderung tidak kompatibel. Jika Anda cukup culun untuk mengikuti sejauh ini, mari kita dapatkan crackalackin dengan beberapa contoh buah sialan!
Sistem Stank mencakup perpustakaan Stank Go serta beberapa utilitas baris perintah untuk kenyamanan. Aplikasi stank memindai direktori dan file untuk skrip shell yang diturunkan POSIX dan mencetak jalurnya, dirancang sebagai filter mandiri yang nyaman untuk pengumpulan besar kode sumber besar.
$ cd examples
$ stank .
.profile
.shrc
.zlogin
... Utilitas baris perintah stank mencari jalur file untuk skrip shell yang mungkin menjamin linting.
Stank terintegrasi dengan linter eksternal, membantu memberi mereka set jalur file yang lebih terfokus untuk dianalisis dalam direktori proyek yang lebih besar.
$ 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... File yang dihasilkan mesin, termasuk file git hook default *.sample , secara otomatis dilewati.
Lihat stank -help untuk opsi tambahan.
https://github.com/mcandre/stank/releases
$ go install github.com/mcandre/stank/...@latesthttps://pkg.go.dev/github.com/mcandre/stank
funk Linter melaporkan bau aneh yang berasal dari skrip, seperti ujung garis yang tidak tepat, keberadaan penanda pesanan byte dalam beberapa skrip 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 Baik stank dan funk memiliki kemampuan untuk memilih skrip level rendah, nonposix juga, seperti skrip CSH/TCSH yang digunakan dalam FreeBSD.
Perhatikan bahwa Funk tidak dapat memperingatkan dengan andal karena kehilangan shebangs jika ekstensi juga hilang; Biasanya, penulis skrip menggunakan satu atau yang lain untuk menandai file sebagai skrip shell. Kurangnya shebang dan ekstensi file, berarti bahwa file dapat berisi kode untuk banyak bahasa, sehingga sulit untuk menentukan sifat positif dari kode tersebut. Bahkan jika serangkaian AST yang lengkap diterapkan untuk menguji konten file untuk validitas sintaksis di seluruh lusinan bahasa shell yang tersedia, ada kemungkinan kuat dalam file yang lebih pendek bahwa kontennya hanyalah sintaks skrip yang valid secara kebetulan, meskipun maksud file tidak beroperasi sebagai skrip shell POSIX. Skrip pendek, nonposix seperti untuk CSH/TCSH dapat dengan mudah memicu kecocokan sintaks "POSIX". Bagaimanapun, ketahuilah bahwa shebang diperlukan untuk memastikan skrip Anda ditafsirkan dengan benar.
Perhatikan bahwa Funk mungkin gagal menyajikan peringatan izin jika skrip ditempatkan pada sistem file non-UNIX seperti NTFS, di mana bit yang dapat dieksekusi sering hilang dari file metadata sama sekali. Saat menyimpan skrip shell, pastikan untuk mengatur izin file yang sesuai, dan mentransfer file sebagai bundel dalam tarball atau mirip dengan perlindungan terhadap izin yang dijatuhkan.
Perhatikan bahwa Funk dapat memperingatkan ketidakcocokan interpreter untuk skrip dengan titik -titik asing di nama file. Daripada .envrc.sample , beri nama file sample.envrc . Daripada wget-google.com , beri nama file wget-google-com . Menambahkan .sh juga merupakan opsi, jadi update.es.cluster mengganti nama menjadi update.es.cluster.sh .
Bendera opsional -modulino untuk funk memungkinkan pemisahan tugas skrip yang ketat, menjadi skrip aplikasi yang berbeda vs skrip perpustakaan. Skrip aplikasi umumnya dieksekusi dengan memohon jalur, seperti ./hello atau ~/bin/hello atau hanya hello ketika $PATH dimodifikasi dengan tepat. Skrip Aplikasi Fitur Pemilik Izin yang Dapat Dieksekusi, dan mungkin grup dan lainnya juga tergantung pada kebutuhan konfigurasi sistem. Sebaliknya, skrip perpustakaan dimaksudkan untuk diimpor dengan dot ( . ) Atau source ke shell pengguna atau skrip lain, dan harus menampilkan ekstensi file seperti .lib.sh , .sh , .bash , dll. Dengan menggunakan konvensi penamaan yang terpisah, kami lebih cepat berkomunikasi dengan pengguna hilir cara berinteraksi dengan skrip shell. Secara khusus, dengan menjatuhkan ekstensi file untuk aplikasi skrip shell, kami mendorong penulis untuk memilih nama skrip yang lebih bermakna. Alih-alih build.sh generik, pilih build-docker . Alih-alih kafka.sh , pilih start-kafka , kafka-entrypoint , dll.
Akhirnya, stink mencetak catatan dari posixyness masing -masing file, termasuk bidang menarik yang diidentifikasi di sepanjang jalan. Perhatikan bahwa beberapa bidang mungkin nol bernilai jika bau POSIX atau waft kemerahan nonposix sangat luar biasa, analisis pendekatan pendek. Fitur singkat ini secara dramatis mempercepat bagaimana stank mencari proyek besar.
Perhatikan bahwa izin disampaikan sebagai desimal, karena kendala pada pemformatan integer JSON (kami tidak ingin menggunakan bidang string oktal khusus). Gunakan echo 'obase=8;<some integer> | bc untuk menampilkan nilai -nilai ini dalam oktal.
Perhatikan bahwa sistem warisan, paket, dan skrip shell yang merujuk "sh" dapat merujuk pada sejumlah besar cangkang pra-posix. Sistem modern mengganti nama "sh" menjadi "lksh", "tsh", "etsh", dll. Untuk menghindari kebingungan. Secara umum, Stank Suite akan mengasumsikan bahwa sebagian besar skrip yang dipindai menargetkan teknologi pasca-1971, jadi gunakan intuisi dan konteks manusia Anda untuk mencatat setiap warisan Thompson Unix v6 "sh", dll. Script. Sebagian besar linter modern tidak akan dapat menguraikan skrip semacam itu dari kompleksitas apa pun, mereka juga tidak akan mengenalinya untuk skrip warisan seperti itu, kecuali jika sajian naskah itu diberikan dengan penafsir retro modern "lksh", "tsh", "etsh", dll. Untuk penempatan pada sistem Unix modern. Orang hampir dapat menggunakan statistik FS untuk modifikasi/perubahan untuk mencoba mengidentifikasi outlier warisan ini, tetapi ini adalah asumsi praktis yang tidak realistis kecuali untuk arkeolog yang paling obsesif, dengan rajin memastikan skrip warisan mereka terus menyajikan metadata tahun 1970 bahkan setelah modifikasi konten eksperimental. Jadi Sistem Stank hanya akan menyepak bola dan menganggap Sh -> POSIX SH, KSH -> KSH88 / KSH93 demi modernitas dan keseimbangan.
Demikian pula, shell bourne lama alias "sh" alias "bsh" menghadirkan kesulitan identifikasi bahasa. Naskah Old Bourne Shell kemungkinan besar akan menampilkan diri mereka dengan Shebangs "Sh", yang tidak apa -apa karena Bourne SH dan KSH88/PDKSH/KSH berfungsi sebagai pangkalan untuk standar POSIX SH. Beberapa sistem modern dapat menyajikan cangkang Bourne sebagai biner "sh" atau "bsh". Yang pertama menyajikan beberapa masalah untuk identifikasi stank, meskipun "BSH" rumit, karena sebagian besar penggunaannya saat ini tidak terkait dengan shell Bourne tetapi dengan Java Beanshell. Jadi Stank dapat default untuk memperlakukan skrip bsh sebagai non-posixy, dan skrip shell bourne semacam itu disarankan untuk menampilkan bash atau sh , dan mungkin ekstensi .bash .sh untuk mengidentifikasi diri sebagai skrip modern yang patuh 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/ direktori yang disertakan menunjukkan banyak kasus tepi, seperti skrip kosong, skrip tanpa shebang, skrip yang diperpanjang dan tanpa ekstensi, dan berbagai aplikasi Hello World di banyak bahasa pemrograman. Beberapa file, seperti examples/goodbye mungkin berisi 100% konten skrip posix shell yang valid, tetapi gagal mengidentifikasi diri dengan shebangs atau ekstensi file yang relevan. Dalam proyek besar, file tersebut dapat diperlakukan secara keliru sebagai format whoknowswhat, atau hanya teks biasa. Mungkin metode statistik dapat membantu mengidentifikasi tata bahasa POSIX, tetapi bahkan file kosong secara teknis adalah POSIX, yang tidak membantu dari sudut pandang klasifikasi yang andal. Bagaimanapun, examples/ semoga mencakup kasus tepi yang lebih umum.
Salah satu cara untuk memikirkan stank adalah pemburu hadiah untuk skrip shell.
Mengingat bahwa shell cenderung lebih rapuh daripada bahasa pemrograman tingkat yang lebih tinggi, maka itu adalah ide yang baik untuk menulis ulang kode shell sebagai aplikasi khusus. Go dan Rust adalah pilihan yang sangat baik untuk bahasa aplikasi.
Bahasa pemrograman karat memiliki kinerja, keandalan, dan keamanan kelas yang terbaik. Bahasa pemrograman GO memiliki kinerja, keandalan, dan keamanan yang sebanding dalam sebagian besar konteks. Baik Rust dan GO mendukung kompilasi silang dan executable statis, sehingga jauh lebih mudah untuk mengembangkan, menguji, mengemas, dan mendistribusikan aplikasi Rust/GO dibandingkan dengan skrip shell yang bersisik. Sebagian besar coders shell lalai untuk mempertimbangkan masalah penguncian vendor halus dengan sintaks shell dan bendera yang digunakan untuk perintah individual. Rust memiliki kurva belajar yang lebih curam daripada beberapa coder yang bersedia mencurahkan waktu. Seringkali, pergi dapat berfungsi sebagai kompromi. Menjadi bahasa yang dikompilasi, baik karat maupun go dilindungi dari banyak perangkap runtime yang diundang oleh cangkang dan bahasa yang ditafsirkan lainnya.
Terlepas dari itu, bahasa pemrograman tertentu adalah keprihatinan yang kurang penting, asalkan bukan shell. Bahasa pemrograman yang terkenal berbahaya seperti JavaScript dan Perl, masih lebih aman daripada shell. Shell (rasa apa pun) adalah api sampah yang menunggu percikan.
Untungnya, daftar skrip shell yang dipancarkan stank , dapat membantu para insinyur untuk mengidentifikasi kandidat program untuk menulis ulang dalam bahasa pemrograman yang lebih matang.
BSD-2 Clause
(Tidak ada)
Untuk detail lebih lanjut tentang pengembangan Stank itu sendiri, lihat Development.md.
Perhatikan bahwa sangat banyak komponen perangkat lunak memiliki kebiasaan buruk untuk mendorong cuplikan skrip shell inline tertanam ke dalam file skrip non-shell. Misalnya, konfigurasi pekerjaan CI/CD, langkah menjalankan DockerFile, sumber daya Kubernetes, dan buat. Sebagian besar alat linter (untuk skrip shell dan bahasa lain) memiliki dukungan yang sangat terbatas atau tidak ada untuk linting inline shell skrip cuplikan.
Dengan demikian, pindahkan cuplikan skrip shell ke file skrip shell khusus. Dan kemudian minta komponen perangkat lunak menjalankan skrip shell. Maka Anda akan dapat memasukkan kode shell dengan lebih banyak alat, dan dengan demikian meningkatkan tingkat kualitas sistem Anda.
Beberapa file yang agak tidak jelas, seperti kode sumber LISP umum dengan multiline, shebangs polyglot dan tidak ada ekstensi file, dapat secara keliru memicu perpustakaan STANK, dan aplikasi bau dan stank, yang sirkuit pendek pada baris pertama hacky shebang. File seperti itu dapat diidentifikasi secara salah sebagai kode "POSIX", yang sebenarnya merupakan perilaku yang dimaksud! Ini karena polyglot shebang adalah peretasan untuk mengatasi keterbatasan dalam bahasa lisp umum, yang biasanya tidak menerima komentar posix shebang, untuk mendapatkan skrip lisp umum dapat ditampar dalam bash. Untuk situasi ini, yang terbaik adalah menyediakan ekstensi file yang tepat ke file tersebut.
$ 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
} Mungkin menambahkan ekstensi .lisp ke file tersebut. Atau pisahkan modulino ke dalam modul Clear Library vs Command Line. Atau ekstrak interaksi shell ke dalam skrip khusus. Atau meyakinkan pengelola bahasa untuk memperlakukan shebangs sebagai komentar. Tulis anggota kongres Anda. Bagaimanapun Anda menyelesaikan ini, ketahuilah bahwa situasi saat ini jauh di luar norma, dan cenderung pecah dengan cara yang misterius dan dramatis. Dengan wyvern dan lautan yang menyala dan pertanda dari semua cara yang sakit.
Bois yang buruk ini membantu menopang skrip shell Anda. Meskipun mereka dirancang untuk bekerja pada file individual, jadi pastikan untuk menyiram proyek yang lebih besar dan menyalakan hasilnya ke xargs [-0] [-n ... shellcheck .
ACK menawarkan --shell [-f] bendera yang bertindak mirip dengan stank , dengan peringatan bahwa ACK mencakup cangkang nonposix seperti CSH, TCSH, dan FISH dalam hasil ini; Tetapi pada tulisan ini gagal memasukkan cangkang POSIX seperti Ash, Dash, Posh, PDKSH, KSH93, dan MKSH. ACK juga tergantung pada Perl, membuatnya lebih berat untuk Microservices Docker dan platform terbatas lainnya.
Kirill mengidentifikasi dokumen JSON.
Ahli bahasa, upaya luar biasa GitHub untuk mengidentifikasi bahasa mana yang masing -masing jutaan repositori ditulis. Sementara proyek Stanky Go ini tidak menggunakan ahli bahasa dalam analisis otomatis, ada baiknya disebutkan untuk tujuan forensik, jika Anda pernah menemukan file kode sumber yang aneh, tidak dikenal (atau salah diidentifikasi!).
Linters, wiki dari linter bahasa pemrograman umum dan alat SAST.
Periscope memperingatkan pada paket NPM yang tidak berotot.
Sail mengidentifikasi file kode sumber C/C ++.
Slick menawarkan sintaks sh -n Pemeriksaan terhadap sintaks murni POSIX, sedangkan sh aktual pada sebagian besar sistem symlink untuk bash.
Buka, linter untuk makefile.