Những chương trình Shell lớn nhất thế giới
(github.com/oils-for-unix)- Wiki này không chỉ là danh sách các script dài, mà tập hợp các chương trình Shell “thực chất” được viết thủ công và có sử dụng cả cấu trúc dữ liệu và thuật toán
- Tiêu chí nhìn chung là từ 5K dòng trở lên, còn các script sinh tự động hoặc các script completion mang tính lặp lại bị loại khỏi các ví dụ cốt lõi
- Các ví dụ tiêu biểu như ble.sh 87K dòng, kalua khoảng 56K SLoC/dòng, Relax-and-Recover 35K dòng, nb 26K dòng, winetricks 22K dòng vượt xa nhận thức thông thường về Shell script
- Danh sách bao gồm rộng rãi các công cụ dùng thực tế như trình soạn thảo dòng tương tác, add-on OpenWRT, trình gỡ lỗi Bash, công cụ kiểm thử TLS, triển khai Kubernetes, công cụ sao lưu/khôi phục, công cụ cấp chứng chỉ, trình giám sát tài nguyên, v.v.
- Kiểm thử OSH “Wild” phân tích cú pháp hơn một triệu dòng Shell, nhưng phần lớn là các chương trình nhỏ và định nghĩa gói bản phân phối có tính lặp lại, nên được phân biệt với các chương trình Shell lớn
Thế nào được xem là “chương trình Shell lớn”
- Ở đây, “biggest” không chỉ nói đến số dòng thô, mà là “substantial”, tức quy mô và độ phức tạp thực chất
- Đối tượng được đưa vào về cơ bản là Shell script viết thủ công
- Các script lớn do autoconf sinh ra được xem là ngoại lệ
- Các sản phẩm sinh tự động như script coreutils 70K dòng không được xem là chương trình Shell lớn theo nghĩa thực chất
- Đặc biệt coi trọng các chương trình Shell dùng cấu trúc dữ liệu và thuật toán
- bash-completion tuy tinh vi, nhưng có cấu trúc lặp lại với các hàm tương đối đơn giản cho từng lệnh trên máy Unix, nên gần với một phản ví dụ hơn
- Ngưỡng tham chiếu xấp xỉ là trên 5K dòng
- Các chương trình Shell lớn nhất không mang tính lặp lại thường nằm trong khoảng 10K+ dòng
- Hiện chưa xác nhận được chương trình nào vượt 100K dòng
Các ví dụ về chương trình Shell lớn nhất
- akinomyoga/ble.sh: tổng cộng 87K dòng, 63K LoC nếu không tính chú thích
- Đây là trình soạn thảo dòng tương tác giống fish, viết bằng bash thuần
- File chính
out/ble.shcó 39K dòng, 29K LoC nếu không tính chú thích; cộng cả các file module thì tổng cộng hơn 80K dòng - Có nhiều chú thích tiếng Nhật
- Dùng
bind -xđể đọc raw bytes của terminal, tự giải mã bằng nhiều state machine tường minh, đồng thời duy trì và cập nhật drawing buffer - Cũng bao gồm timing và “fibers”
- Chi tiết liên quan đến Shell parser nằm trong bình luận của issue 663, và được đánh giá là một trong những ví dụ dùng cấu trúc dữ liệu trong Shell tinh vi nhất
- Đã có nỗ lực chạy trên OSH và phần lớn đều được phân tích cú pháp
- Commit đầu tiên vào năm 2015 có 8K dòng / 6K LoC, còn quá trình phát triển thực tế bắt đầu từ năm 2013
- kalua: add-on OpenWRT, viết bằng POSIX shell với khoảng 56K SLoC/dòng
- Relax-and-Recover: công cụ sao lưu/khôi phục 35K dòng, 24K LoC
- Commit git đầu tiên vào tháng 3/2009, khi đó có 4K dòng / 3K LoC
- xwmx/nb: bản thân
nbđược viết bằng bash, có 26K dòng, 22K LoC- Nếu tính các test bats bằng bash thì có thêm 91K dòng, 61K LoC
- Commit đầu tiên vào năm 2014, lịch sử commit sôi động bắt đầu từ đầu năm 2016
- vegardit/bash-funk: thư viện Bash tổng cộng 27K dòng, 24K LoC
- Commit đầu tiên vào tháng 5/2017, khi đó có 10K dòng / 8K LoC
- winetricks: Shell script 22K dòng, cài đặt nhiều chương trình Windows dưới Wine
- drwetter/testssl.sh: một file duy nhất chứa 21K dòng bash
- Có vẻ được viết thủ công
- Bắt đầu vào năm 2006 với vài lệnh
openssl - Gặp issue #606 trong quá trình phân tích cú pháp
- rkhunter: chương trình Bourne shell 21K dòng, được viết từ năm 2003 đến 2018
- Trang chính thức là rkhunter.sourceforge.net
- Simplenetes: được giới thiệu là “Kubernetes in 17K lines of Shell”
- Được đánh dấu là một trường hợp đáng kinh ngạc, nhưng có vẻ đang ở trạng thái dormant
- Có liên kết tới Hacker News Thread liên quan
- inxi 2.3.56: chương trình bash 16K dòng được đánh dấu là obsolete
- Được fork từ
infobashvào năm 2008 - Khi đó
infobashcó 889 dòng, vàinfobashbắt đầu từ năm 2005 - Từ v2.9,
inxiđược thay thế bằng bản triển khai Perl
- Được fork từ
- bashdb: trình gỡ lỗi Bash, viết bằng bash với khoảng 14K dòng
- Có liên kết tới Implementing Debuggers làm bối cảnh liên quan
- romkatv/powerlevel10k: thư mục
internal/có 12K dòng zsh script- Ngoài ra còn có 8K dòng config và helper script
- Commit đầu tiên vào năm 2014
- dylanaraps/neofetch: chương trình 10K dòng viết bằng Bash 3.2, hiển thị thông tin hệ thống
- Cũng có thể làm một số chức năng thú vị liên quan đến hình ảnh
- Commit đầu tiên vào năm 2015
- distrobox: bash script hơn 7K dòng, cho phép dùng bất kỳ bản phân phối Linux nào bên trong terminal
- acme.sh: Shell script 8K dòng, cấp phát và gia hạn chứng chỉ
Các triển khai đáng chú ý dù quy mô nhỏ hơn
- bashforth: khoảng 3.800 dòng, không quá lớn nhưng triển khai một ngôn ngữ lập trình thực sự
- Có nhiều khoảng trắng và chú thích
- yoda: kích thước khoảng một nửa bashforth nhưng triển khai toàn bộ interpreter và compiler
- Là bản triển khai trẻ hơn 20 năm của cùng tác giả, chứa nhiều tính năng hơn
- Có chú thích “What learned you have, unlearn you must!”
Các chương trình Shell quan trọng khác
- abcde / A Better CD Encoder: dùng để CD ripping, khoảng 5.5K LoC
- thc-segfault: 3.3K LoC, là server pubnix phần lớn được làm bằng Bash
- ffmpeg/configure: script configure viết thủ công của FFmpeg, 8.4K LoC
- ffhevc: Bash wrapper hoàn toàn viết thủ công để encode video HEVC bằng FFmpeg và libx265, 4K LoC
- ffx264: Bash wrapper hoàn toàn viết thủ công để encode video H.264/AVC bằng FFmpeg và libx264, 3.9K LoC
- h264enc: Bash wrapper hoàn toàn viết thủ công để encode video H.264/AVC bằng MEncoder, 9.2K LoC
- bashtop: trình giám sát tài nguyên 5.3K LoC
- halcyon: hệ thống cài đặt ứng dụng Haskell, 6.6K LoC
- Mã viết thủ công chú ý đến bash semantics và kiểm tra lỗi, có phong cách độc đáo lấy cảm hứng từ lập trình hàm
- wordshell: khoảng 7K dòng code, quản lý nhiều site WordPress từ dòng lệnh
- BaCon: khoảng 10K dòng, chuyển đổi chương trình viết bằng BASIC sang C
- Có hai bản triển khai: bản BASIC và bản Shell script
- FireHOL: script chính 9K dòng, công cụ FireQOS có thêm 3K dòng
- Vừa là ngôn ngữ vừa là chương trình thực thi để tạo secure, stateful firewall từ cấu hình dễ đọc cho con người
- gxadmin: 11K LoC, là tập hợp templated SQL query và tiện ích xử lý dữ liệu để quản trị engine workflow khoa học Galaxy
- mulle-bashfunctions: thư viện hàm cho bash/zsh, khoảng 6K dòng
- Được dùng trong
mulle-sde, vàmulle-sdelại là một Shell script 100K dòng khác
- Được dùng trong
- x11docker: 11.6K dòng, chạy ứng dụng GUI trong container docker hoặc podman
Ngôn ngữ giống Shell và DSL
- modernish: portable shell dialect viết bằng Shell
- bats: DSL để viết test và sinh mã bash
- bashible: DSL giống Ansible viết bằng bash
- Có liên kết tới comments liên quan
- clash: framework hướng đối tượng tương thích với mọi POSIX shell hiện đại
- bash Infinity: framework boilerplate và thư viện chuẩn cho bash
Các chương trình nhỏ hơn và hệ sinh thái liên quan
- Các script Alpine, Aboriginal, Debian được liên kết trong một blog post riêng
- Các completion script thường lớn nhưng hay mang tính lặp lại
- Zsh completion _git có 8.3K dòng code
git-completion.bashvà Docker completion cũng được nêu làm ví dụ
- dyne/Tomb: zsh script khoảng 3.500 dòng
- Basalt: package manager đầy đủ tính năng viết bằng Bash thuần
- Quy mô vài nghìn dòng, nhưng có rich ecosystem gồm hơn 15 app và thư viện
- bash-core: thư viện mở rộng các builtin
trapvàshopt, đồng thời thêm stacktrace và các tiện ích thiết yếu - bash-object: thư viện dựng cấu trúc dữ liệu lồng nhau tùy ý bằng Bash thuần, có gần 200 test
- bash-json: thư viện phân tích cú pháp và xuất JSON bằng Bash thuần
- tablespoon/fun/cli-clock: đồng hồ chữ nhiều dòng viết bằng bash
- json.bash / jb: công cụ dòng lệnh và thư viện bash để tạo JSON
- Khoảng 1.700 dòng, có khoảng 3.000 dòng test
Kiểm thử OSH và lưu ý khi dùng Shell
- OSH "Wild" Tests phân tích cú pháp hơn một triệu dòng Shell
- Phần lớn là các chương trình nhỏ và định nghĩa gói bản phân phối có tính lặp lại như Alpine
PKGBUILD, Gentooebuild
- Phần lớn là các chương trình nhỏ và định nghĩa gói bản phân phối có tính lặp lại như Alpine
- Shell Programs That Run Under OSH liên kết tới danh sách các chương trình Shell chạy được trên OSH
- shell script are dangerous cảnh báo rằng Shell là chương trình xử lý bên trong hệ thống qua console tương tác hoặc ở chế độ không tương tác; nó có nhiều chức năng, rất nguy hiểm và không được tạo ra để xây dựng ứng dụng
1 bình luận
Các ý kiến trên Hacker News
Đào sâu vào thì hóa ra OMS là một đống shell script khổng lồ chạy trên máy chủ AIX, đã tiến hóa hơn 10 năm rồi bị bỏ mặc. Mã nguồn hơn 50.000 dòng; đơn hàng, thanh toán và các thông tin khác được chuyển giữa các máy chủ qua FTP rồi phân tích bằng các chuỗi sed/awk phức tạp; tồn kho cũng được theo dõi bằng file văn bản và chuyển qua FTP
Lúc đó Perl có vẻ là lựa chọn thực tế nhất để di dời mớ hỗn độn này, nên tôi bắt đầu từ những phần đơn giản nhất, thay bằng các module Perl nhỏ và refactor dần dần bên trong một ứng dụng Perl lớn hơn. Trong 3 tháng, tôi rút toàn bộ xuống còn khoảng 5.000 dòng Perl, lỗi của hệ thống cũ gần như biến mất và tốc độ nhanh hơn 10–100 lần. Thật kinh khủng, nhưng đó là một trong những việc đem lại cảm giác thỏa mãn nhất mà tôi từng làm
Tôi tò mò không biết bạn đã đọc hết mã cũ và hiểu sâu rồi khớp hành vi chính xác, hay bỏ đi những khối lớn và viết lại theo cách bạn nghĩ “nó nên hoạt động như thế này”. Cũng tò mò liệu có nhiều boilerplate có thể thay thế nhanh không
Script thật sự lớn đầu tiên tôi viết là một trình cài đặt khoảng 7.000 dòng cho Enrust CA và thư mục, và nó phải chạy trên gần như mọi Unix thời đó. Ban đầu không phải vậy, nhưng nó phình ra theo yêu cầu của khách hàng
Bản thân việc cài đặt không quá phức tạp, nhưng nâng cấp thì hơi rắc rối, và thời đó mọi tiện ích trên mỗi Unix đều khác nhau một chút. Phần lớn script là mã để phát hiện và quản lý các khác biệt đó, kèm theo phát hiện lỗi, khôi phục, rollback, và cả quản lý gói cùng phụ thuộc ở mức rất sơ khai
Unix của DEC, bản không phải Ultrix, là thứ khó hiểu nhất. Tôi mất vài ngày mới nhận ra rằng mọi tiện ích dòng lệnh đều cắt ngắn đầu ra theo chiều rộng cột của terminal, và 30 năm sau tôi vẫn còn nhớ chuyện đó
HP-UX có thay đổi phá vỡ tương thích ở mỗi bản phát hành, và nếu tôi nhớ đúng thì chúng tôi hỗ trợ từ 6.5 đến 11. Ultrix, phía Novell, NeXT, Sequent thì tôi gần như không nhớ nữa. Tôi nhớ AIX kỳ lạ, nhưng quên mất lý do. Ba/bốn OS của Sun cũng có khác biệt, nhưng tài liệu hướng dẫn thì tuyệt vời và là tốt nhất
wctrên binary chính và thư viện phụ trợ của một dự án thì tới nay là 6.224 dòngĐó là script quản lý một pipeline bảo đảm tuyến tính, gồm các cụm container với adapter giao thức đầu vào, một hoặc nhiều filter, và adapter giao thức đầu ra. Mục tiêu là để những người không phải chuyên gia về container hay giao thức vẫn dùng được, miễn là họ biết mình muốn file được lọc và biến đổi ra sao khi đi qua pipeline
Binary cấp cao nhất có cấu trúc gồm các chức năng con, kiểu như
git [ git options ] < git action> [action options]hoặcsystemctl. Còn có cả lệnh con để thêm lệnh con mới, tạo các thư viện cần thiết và điền sẵn định nghĩa hàm từ template. Template có các hàm hướng dẫn sử dụng ngắn/dài đểcbap -hhoặccbap pipeline -hđưa ra hướng dẫn hữu íchCó các lệnh con để thao tác với image nền, component và pipeline. Phần đáng kể của mã là dành cho kiểm thử nhằm xác nhận định nghĩa component và pipeline được viết đúng. Pipeline có định dạng gần giống TOML nên có mã phân tích TOML và chuyển section thành mảng; component là file
key=valueđơn giản nên có mã trích xuất vế trái/vế phải và kiểm tra schemaVì các component trong pipeline có thể chia sẻ thuộc tính, cũng có mã tìm thuộc tính chung trong các file
varvàetcrồi gán thuộc tính cho component. Ngoài ra còn có nhiều hàm thao tác user, group, thư mục, FIFO theo yêu cầu bảo mật. Khi thiết lập pipeline, nó tạo và áp dụng user, group, loại SELinux, category MCS rồi ánh xạ vào các service file khởi động component, nên cũng có rất nhiều phần thao tác systemdNhóm lệnh gọi lớn nhất có lẽ là các hàm lấy và đặt thuộc tính component, thực chất là thuộc tính container. Với mỗi thuộc tính, tôi có hàm lấy, hàm xác thực và phiên bản inline trong pipeline, để định nghĩa container dựa trên dữ liệu linh hoạt nhất có thể
Cũng có phần mã dùng rất nhiều tham chiếu Bash để đặt biến từ file, biến môi trường và dòng lệnh, giúp kiểm thử nhanh. Nó hỗ trợ bốn cấp người dùng: maintainer làm việc trực tiếp với mã, developer phát triển định nghĩa component, integrator tạo pipeline từ component, và operator cài đặt pipeline; nó có thể tự sao chép và đóng gói chính mình để xuất cho người dùng ở từng cấp
Vì hệ thống đích có thể là bất kỳ Linux nào, nó được đóng gói và giải nén bằng
makeself. Ví dụ khi integrator tạo định nghĩa pipeline, một filemakeselfđược tạo ra; khi chạy trên hệ thống đích, nó tạo tất cả user, group, thư mục, FIFO, tức IPC giữa các component, áp dụng DAC/MAC, tạo file systemd, sao chép image cho từng user rồi chạy pipeline. Tùy chọn gỡ bỏ cũng có thể đảo ngược tất cả việc nàyCó cả một phần seccomp, nhưng hiện đang tạm dừng vì cần tìm điểm cân bằng giữa allowlist và blocklist. ShellCheck thì được dùng cực kỳ kỹ
Cũng không thể kỳ vọng mọi môi trường đều có
bc/dc, và một số máy tôi có dùng phiên bản Bash cũ nên hỗ trợ mảng kết hợp cũng rất hạn chế. Phương án thỏa hiệp là nhắm tới AWK; AWK là một ngôn ngữ đa dụng dễ chịu hơn hầu hết shell rất nhiều và có mặt ở mọi môi trường POSIX: https://beyondloom.com/blog/lila.htmlbc/dcTôi khá ngạc nhiên vì hình như bản cài Ubuntu trên WSL2 không có
bc/dc. Tôi đang dùng AWK để tính toán số thực dấu phẩy động, nhưng chỉ là gọi nó như một tiến trình bên ngoài.Từ góc nhìn của người đã nhiều lần viết và bảo trì các chương trình Perl lớn trong sự nghiệp, việc người ta làm như vậy là có lý do
Những ngôn ngữ như Java hay Python phù hợp khi giao diện và kiểu dữ liệu đã được định nghĩa, và gần như không có tương tác với OS. Nếu dùng JSON/XML/YAML, hoặc giao tiếp với cơ sở dữ liệu, chương trình khác qua HTTP(S), thì đó là tình huống lý tưởng để các ngôn ngữ này tỏa sáng
Nhưng khi xử lý lượng lớn văn bản và tương tác với OS, Java và Python trở thành một nỗi khổ lớn. Ngược lại, Shell/Perl khiến các công việc kiểu này dễ chịu hơn nhiều
Gần như mọi tác vụ tự động hóa, các giao diện hỗn loạn và không được chuẩn hóa, file văn bản/log, các định dạng dữ liệu không có cấu trúc hoặc chưa đủ cấu trúc đều thuộc nhóm này. Nếu cộng thêm khả năng tương thích ngược của Perl, phạm vi cài đặt rộng và hiệu năng, thì thực tế gần như không có lựa chọn thay thế Perl cho các công việc như vậy
Từ lâu tôi đã thấy rằng một trong những lý do lớn khiến các tập đoàn hiện nay có quá nhiều lao động thủ công, phải thuê hàng nghìn người để làm những việc có thể tự động hóa một cách vụn vặt, là vì việc dùng Perl đã giảm. Khi thử làm một tác vụ tự động hóa lớn bằng Python hay Java, người ta nhanh chóng bỏ cuộc vì sự dài dòng của lượng code phải viết/bảo trì và quy mô tổng thể của nó
Vì vậy có lẽ giờ cần thêm nhân sự chính thức đắt tiền. Nếu người dùng cuối dùng Windows thì trên desktop đã có sẵn một lựa chọn giống Perl. Đó là PowerShell, và nó đóng vai trò tương tự Perl
Bash+grep dễ dẫn đến kiểu chạy một tiến trình mới cho mỗi dòng văn bản. Muốn hiệu quả thì phải giảm thiểu công việc, và để làm vậy cần xử lý theo batch và loại bỏ trùng lặp. Điều này nghĩa là phải xử lý dữ liệu theo cách có trạng thái, đồng thời theo dõi ngữ cảnh loại bỏ trùng lặp, và việc đó dễ hơn trong một ngôn ngữ lập trình đúng nghĩa
Bash+grep có lợi cho xử lý văn bản không trạng thái nên dễ làm tăng mức trùng lặp công việc. Một cách khác để giảm công việc là lọc chính xác, mà điều này thường dễ diễn đạt gọn gàng theo lối mệnh lệnh trong một ngôn ngữ đúng nghĩa hơn. grep và biểu thức chính quy hoàn toàn không phù hợp cho mục đích này
Nếu dùng định dạng theo dòng, git sẽ thêm escape để cố chấp nhận mọi thứ, nhưng hỗ trợ không nhất quán và có thể vô hiệu hóa bằng cách yêu cầu định dạng chuỗi kết thúc bằng null với tùy chọn
-z. Có vẻ Bash không có cách xử lý việc này, còn trong một ngôn ngữ đủ cấp thấp thì có thể xử lý rất tự nhiên. Ngoài ra cũng có thể streaming tăng dần mà không cần khởi chạy tiến trình mới cho từng dòng văn bảnThêm nữa, dù ở giữa có HTTP hay thứ gì khác, vẫn có thể dùng một codebase duy nhất cho mọi tác vụ
Có vài liên kết để cung cấp ngữ cảnh. “Có phải đang phát minh lại Perl không?”: https://www.oilshell.org/blog/2021/01/why-a-new-shell.html#a...
“Unix shell nên tiến hóa như Perl 5, với các tùy chọn nâng cấp tương thích, chứ không phải một vụ Big Bang như Perl 6/Raku”: https://www.oilshell.org/blog/2020/07/blog-roadmap.html#the-...
Tham quan YSH: https://www.oilshell.org/release/latest/doc/ysh-tour.html
Điều này có thể không trông giống một lợi thế lớn cho đến khi bạn phải làm việc trong môi trường không thể cài gì đó từ Internet, hoặc hoàn toàn không thể truy cập Internet
Vấn đề cốt lõi khi viết một chương trình lớn bằng Bash script là ngôn ngữ shell script vốn không được thiết kế cho sự phức tạp
Nó rất xuất sắc trong việc điều phối các lệnh nhỏ và nhanh chóng nối các công cụ sẵn có theo kiểu thăm dò, nhưng khi Bash bắt đầu vượt quá vài trăm dòng, các giới hạn khiến việc bảo trì dài hạn và mở rộng trở nên đau đầu sẽ liên tiếp xuất hiện
Trước hết là khả năng đọc hiểu. Cú pháp Bash có thể trở nên thật sự rối rắm khi chương trình lớn lên. Quy tắc phạm vi biến rất tinh vi, xử lý lỗi còn thô sơ, và xử lý chuỗi nhanh chóng trở nên bừa bộn. Cuối cùng, người bảo trì phải lãng phí thời gian để giải mã xem chuyện gì đang xảy ra, và cũng khó thay đổi một cách tự tin
Tiếp theo là thiếu công cụ vững chắc. Các ngôn ngữ trưởng thành hơn có công cụ phân tích tĩnh, linter, debugger để bắt các lỗi phổ biến từ sớm. Trong Bash, những thứ này không có hoặc rất hạn chế. Không có các lớp bảo vệ này, chương trình Bash lớn dễ bị lỗi âm thầm, hồi quy và các bug tinh vi hơn
Kiểm thử cũng là vấn đề. Có thể test Bash script, nhưng quá trình này thường phiền phức hơn, và càng khó hơn nếu có logic hoặc cấu trúc dữ liệu phức tạp. Khi xử lý các trường hợp biên như khoảng trắng trong tên file hoặc điều kiện môi trường bất ngờ, bạn sẽ có rất nhiều code phòng thủ mà việc xác minh trở nên khổ sở
Cuối cùng, bản thân hệ sinh thái không được tạo ra cho phát triển Bash quy mô lớn. Bạn mất đi module hóa, quản lý package, xử lý dependency chuẩn hóa, và các mẫu hình phát triển hiện đại mà Python hay Go cung cấp. Theo thời gian, những thiếu hụt này tích tụ và làm chậm tiến độ
Dùng Bash cho công việc một lần hoặc tự động hóa đơn giản thì ổn. Đó là việc Bash làm tốt. Nhưng nếu định xây dựng thứ gì đó lớn, thông thường nên dùng một ngôn ngữ được thiết kế để xây dựng và bảo trì ứng dụng phức tạp; dù đường cong học ban đầu hay phần thiết lập có cao hơn một chút, về lâu dài nó sẽ tiết kiệm thời gian
Dùng ShellCheck làm linter có thể bắt được rất nhiều bẫy phổ biến. Bash/shell thật sự có rất nhiều bẫy và hành vi ngoài dự đoán, đến cả người viết Bash có kinh nghiệm cũng có thể mắc phải
Tuy vậy, Bash/shell chiếm một vị trí khá đặc biệt trong hệ phân cấp ngôn ngữ. Nó gần như có ở khắp nơi và nhiều khả năng vẫn sẽ còn tồn tại sau 30 năm nữa. Nếu bạn muốn một chương trình chạy được gần như ở mọi nơi và vẫn chạy được sau 30 năm nữa, shell/Bash là một lựa chọn tốt
Nó cũng không phải script được viết từ rất lâu trước đây, nên tôi không hiểu vì sao họ lại chọn Bash. Script thì chạy được, nhưng cảm giác chỉ cần nhìn sai vào code thôi là thứ gì đó sẽ vỡ
-xChương trình shell thủ công lớn nhất mà trước đây tôi dùng thường xuyên có lẽ là abcde (A Better CD Encoder), khoảng 5.500 dòng
https://abcde.einval.com
https://git.einval.com/cgi-bin/gitweb.cgi?p=abcde.git;a=blob...
Rất nhiều chương trình kiểu này thật sự là những viên ngọc quý. Ví dụ script rkhunter có code khá ổn, còn có chỗ để cải thiện, và cũng là một kho thông tin
Một phần lớn kích thước code của những script như vậy được dùng để bảo đảm các tiện ích cần thiết có tồn tại trên nhiều nền tảng hay không, và chúng có hoạt động đúng như kỳ vọng với nhiều tùy chọn dòng lệnh khác nhau hay không. Đây là điểm đau nhất với người viết shell script nghiêm túc, còn khó chịu hơn cả signal và subprocess
Nếu rkhunter được viết bằng một ngôn ngữ lập trình “đúng nghĩa”, có lẽ những thông tin này sẽ kém minh bạch hơn. Chúng có thể bị đẩy vào các record trong cấu trúc dữ liệu để tra cứu, hoặc vận hành qua nhiều hàm trên các cấu trúc dữ liệu lồng nhau, tệ hơn nữa là bằng một tổ hợp method và class. Log cũng có thể bị băm thành JSON, nén vào database và phải truy cập bằng method khác
Vì shell script không có những công cụ phức tạp đó, nên ngược lại nó có xu hướng phơi bày nguyên trạng chuyện gì đang diễn ra. Vì thế rkhunter cũng đóng vai trò như một tài liệu khá tốt về nhiều exploit và rootkit, và ít phải đào từ file này sang file khác, từ cấu trúc này sang cấu trúc khác, từ database này sang database khác
Client FreeBSD Update có khoảng 3.600 dòng code sh
So với các chương trình khác được nhắc đến ở đây thì không lớn, nhưng xét lượng chức năng là “công cụ cập nhật toàn bộ hệ điều hành” thì tôi cho là khá nặng ký. Code dùng để build bản cập nhật được chia thành nhiều file, nên cộng lại chắc sẽ còn nhiều hơn
poudrierexét theo code sh thì cỡ khoảng 3 client FreeBSD Update: https://github.com/freebsd/poudriere/blob/master/src/share/p...Tuy “chỉ” 7,1 nghìn dòng, thứ tôi thích là script acme.sh dùng để phát hành và gia hạn chứng chỉ từ Let’s Encrypt
https://github.com/acmesh-official/acme.sh/blob/master/acme....
Đôi khi thứ duy nhất bạn có thể bảo đảm là dùng được chỉ là shell, và cũng có những tình huống bắt buộc cần tính di động
Nhưng nói chung, nếu bạn có một ứng dụng shell khổng lồ, có lẽ bạn nên suy nghĩ lại về các lựa chọn trong đời mình
Hơn nữa, thường thì chỉ shell thôi không làm được nhiều việc, bạn cần các lệnh như
find,grep,sed,cat,head,tail,cut. Những lệnh này cũng có vấn đề về tính di động riêngNhắm tới BusyBox có thể là lựa chọn tốt nhất, nhưng ngay khi rời khỏi các hệ thống Linux thông thường, việc viết script Bourne shell có tính di động trở nên khó hoặc gần như bất khả thi
Chỉ cần có trình biên dịch C là bạn có thể thoát khỏi shell bằng cách viết chương trình C rồi để shell script phối hợp chúng, hoặc cài một ngôn ngữ script tốt hơn như Lua. Ở thời điểm hiện tại, những trường hợp nhất thiết phải dùng mỗi shell có vẻ khá ngách