BusyBox là gì?
(specular.fi)- BusyBox là một multicall binary cung cấp nhiều lệnh trong một tệp thực thi duy nhất; ngay cả
wgetmặc định của Alpine cũng được chạy thông qua BusyBox - Trong container Alpine,
/usr/bin/wgetkhông phải binary thực sự mà là một liên kết tượng trưng trỏ tới/bin/busybox - Khi chạy, BusyBox đọc tên được gọi từ
argv[0]và dùng tên cuối cùng của đường dẫn để quyết định applet nào sẽ được thực thi - Mỗi applet được tìm theo tên rồi đi vào hàm
maintương ứng;wgetđược triển khai trongwget.cvà cuối cùng chạywget_main - Có thể kiểm tra các lệnh đã được biên dịch bằng
busybox --list; trong ví dụ Alpine, có 304 lệnh được hiển thị và mỗi tiện ích trông như một phiên bản rút gọn
Cách BusyBox hoạt động
- BusyBox sử dụng cấu trúc multicall binary, cung cấp nhiều lệnh trong một tệp thực thi duy nhất
- Trong container Alpine,
/usr/bin/wgetkhông phải là tệp thực thi thật mà là một liên kết tượng trưng trỏ tới/bin/busyboxdocker run --rm -it alpine sh / # which wget /usr/bin/wget / # ls -lah /usr/bin/wget lrwxrwxrwx 1 root root 12 Apr 15 04:51 /usr/bin/wget -> /bin/busybox - Trong
/usr/bin, có hơn 130 tệp thực thi trông như được tạo ra từ một binary duy nhất, điều này gắn liền với cấu trúc multicall binary của BusyBox - Khi chạy, BusyBox lấy tên được gọi từ
argv[0], sau đó chỉ lấy phần tên cuối của đường dẫn để quyết định sẽ chạy applet nàoapplet_name = argv[0]; if (applet_name[0] == '-') applet_name++; applet_name = bb_basename(applet_name); - Nó cũng hoạt động nếu truyền rõ tên applet như
busybox ls -1; nếu đưa vào tên không tồn tại thì sẽ in raapplet not found/ # busybox ls -1 bin dev etc home / # busybox meheh meheh: applet not found
Cấu trúc applet và cách cài đặt
- BusyBox tìm applet theo tên rồi gọi hàm
maincủa applet đóint applet = find_applet_by_name(name); // ... run_applet_no_and_exit(applet, name, argv); // ... xfunc_error_retval = applet_main[applet_no](argc, argv); - Mỗi applet có một tệp C riêng;
wgetđược triển khai trongwget.c - Thiết lập cho từng applet được định nghĩa dưới dạng chú thích trong mã nguồn; cấu hình
WGETbao gồmwget (41 kb), được bật mặc định, phần trợ giúp mô tả đây là tiện ích tải tệp không tương tác từ máy chủ HTTP và FTP, cùng với mục tiêu build làwget.o//config:config WGET //config: bool "wget (41 kb)" //config: default y //config: help //config: wget is a utility for non-interactive download of files from HTTP //config: and FTP servers. //applet:IF_WGET(APPLET(wget, BB_DIR_USR_BIN, BB_SUID_DROP)) //kbuild:lib-$(CONFIG_WGET) += wget.o - Cuối cùng, applet
wgetđi vàowget_mainint wget_main(int argc UNUSED_PARAM, char **argv) - BusyBox cũng hỗ trợ hard link; trong
busybox --install -s,-scó nghĩa là tạo liên kết tượng trưngbusybox --install -s - Có thể xem danh sách các lệnh được đưa vào bản biên dịch bằng
busybox --list; trong môi trường Alpine ví dụ, có 304 lệnh/ # busybox --list | wc -l 304 - Nhiều lệnh trong Alpine hoạt động như giao diện tới binary dựa trên BusyBox, và mỗi tiện ích trông như một phiên bản rút gọn so với tiện ích gốc đầy đủ
1 bình luận
Ý kiến trên Lobste.rs
Câu trả lời cho câu hỏi được trích dẫn gần với tái triển khai hơn
Giới thiệu về BusyBox có tại https://busybox.net/about.html, và mã nguồn ở https://github.com/vda-linux/busybox_mirror
Việc một chương trình giả vờ mang tên khác với thực tế khá gây khó chịu
Trường hợp tệ nhất là trên macOS chạy
gccnhưng thực ra lại ra clang, và PowerShell cũng hoạt động tương tự. Giá mà cứ dùng tên khác thì tốt hơnNixpkgs phải áp dụng rất nhiều bản vá như https://github.com/NixOS/nixpkgs/…, và ngay cả dự án nổi tiếng như sqlite cũng không ngoại lệ. Trong khi đó, macOS về cơ bản đã chọn con đường đánh lừa bằng đường dẫn
ccSẽ có rất nhiều makefile đã hardcode
gcc, và ở ngữ cảnh khác cũng tương tự. Ví dụ, vì nhiều chương trình hiện có kiểm traxterm-*của biến môi trườngTERMthay vì cơ sở dữ liệuterminfovốn là cách đúng, nên cách chọn tên khác sẽ không hiệu quảKhi chẩn đoán các vấn đề kỳ lạ trong container, tôi thường dùng
podman cp /usr/bin/busybox-static somecontainer:/bintoybox cũng có cấu trúc tương tự
Một số công cụ có vẻ được mang từ nơi khác về hoặc được port sang, nhưng khá nhiều cái đã được triển khai mới cho BusyBox, với mục tiêu giữ cho nó nhỏ gọn và chỉ dùng các tính năng libc hạn chế để khi liên kết tĩnh vẫn biên dịch ra kích thước nhỏ. Một ưu điểm nữa là trong shell script có thể dùng những công cụ này như lệnh tích hợp. Một số được chạy bằng fork+jump thay vì fork+exec, và một vài cái thậm chí có thể chạy như lời gọi hàm thông thường mà không cần fork
Nói thêm, theo Toybox on Wikipedia, “Toybox được Rob Landley bắt đầu vào đầu năm 2006 sau khi ông từ bỏ vai trò bảo trì BusyBox do tranh chấp với Bruce Perens, người tạo ra BusyBox ban đầu”
Trên thực tế đây là một bản tái triển khai. Tuy vậy, nếu giấy phép cho phép thì cũng không có gì đáng ngạc nhiên nếu một phần mã được mượn từ triển khai lớn ban đầu
Theo 'pedia:, BusyBox được Bruce Perens viết lần đầu vào năm 1995, và đến năm 1996 đã được tuyên bố là hoàn thành cho mục đích sử dụng ban đầu. Mục tiêu ban đầu là nhét một hệ thống có thể khởi động hoàn chỉnh, đóng vai trò đĩa cứu hộ và trình cài đặt cho bản phân phối Debian, vào đúng một đĩa mềm. Sau đó nó mở rộng thành bộ công cụ user space cốt lõi tiêu chuẩn trên thực tế cho các thiết bị Linux nhúng và trình cài đặt bản phân phối Linux, và vì mỗi tệp thực thi Linux đều cần thêm vài KB overhead nên việc gộp hơn 200 chương trình thành một sẽ tiết kiệm đáng kể dung lượng đĩa và bộ nhớ
Liên quan đến đó, Toybox cũng có cấu trúc và triết lý tương tự nhưng dùng giấy phép BSD. Tôi nhớ rằng nhà phát triển chính Rob Landley từng cho rằng nếu có một giấy phép dễ được chấp nhận hơn về mặt thương mại thì nó có thể được đưa vào thiết bị Android, và khi đó mọi điện thoại và máy tính bảng Android đều có tiềm năng trở thành môi trường phát triển kiểu Unix. Có vẻ Toybox hiện vẫn là một phần của Android, nhưng nếu không có các công cụ hỗ trợ ở tầng trên như Termux thì Android vẫn không dễ dùng theo kiểu Unix
Càng như vậy hơn khi xét đến việc Google trong nhiều năm đã đe dọa sẽ chặn Termux
Cũng có bản port cho Windows: https://github.com/rmyorston/busybox-w32
Kích thước nhỏ của BusyBox khiến những bản port như vậy trở nên thực tế hơn. Tuy nhiên giờ đây có thể просто chạy Linux bên trong Windows nên có vẻ mức độ liên quan của nó đã giảm bớt