强曰为道

与天地相似,故不违。知周乎万物,而道济天下,故不过。旁行而不流,乐天知命,故不忧.
文档目录

第 1 章:BusyBox 概述

第 1 章:BusyBox 概述

1.1 什么是 BusyBox

BusyBox 是一个将数百个标准 Unix/Linux 工具集成到单个可执行文件中的开源项目。它由 Bruce Perens 于 1995 年发起,目标是在极小的磁盘空间内提供一个功能完整的 POSIX 环境。

“BusyBox: The Swiss Army Knife of Embedded Linux” — BusyBox 官方标语

核心特点

特点说明
单一二进制所有工具编译进一个可执行文件
极小体积静态编译约 1-3MB,动态链接更小
POSIX 兼容提供标准 Unix 接口的子集
可裁剪通过 menuconfig 选择需要的功能
广泛使用Alpine Linux、Android、OpenWrt 等均基于它

历史演变

1995  Bruce Perens 创建 BusyBox(单一 shell 脚本)
1999  Erik Andersen 重写为 C 语言版本
2000  版本 0.x 系列,支持更多 Applet
2005  版本 1.0 发布,功能趋于稳定
2010+ 持续维护,支持现代 Linux 特性
2024  版本 1.36+,支持更多平台

1.2 Applet 机制

Applet(小程序)是 BusyBox 的核心概念。每个 Applet 对应一个标准 Linux 命令。

Applet 工作原理

# BusyBox 通过 argv[0] 判断要执行哪个 Applet
$ ls -la /bin/busybox
-rwxr-xr-x 1 root root 1.2M Jan 1 00:00 /bin/busybox

# 创建符号链接
$ ln -s /bin/busybox /bin/ls
$ ln -s /bin/busybox /bin/cat
$ ln -s /bin/busybox /bin/grep

# 直接调用 Applet
$ busybox ls        # 通过 busybox 命令调用
$ busybox cat       # 通过 busybox 命令调用

# 通过符号链接调用
$ ls               # 实际调用 /bin/busybox,argv[0]="ls"
$ cat              # 实际调用 /bin/busybox,argv[0]="cat"

Applet 列表

BusyBox 包含 300+ 个 Applet,按功能分类:

类别典型 Applet数量
Shellash, sh, bash(受限)~10
文件操作ls, cat, cp, mv, rm, find, grep~50
文本处理sed, awk, cut, sort, uniq, tr~30
网络工具ifconfig, route, wget, ping, nc~40
系统管理mount, umount, ps, kill, df~60
压缩归档tar, gzip, bzip2, xz, zip~15
初始化init, poweroff, reboot~10
其他vi, ed, bc, diff, patch~100+

查看当前编译包含的所有 Applet:

# 列出所有可用 Applet
$ busybox --list

# 带分类的列表
$ busybox --list-full

# 示例输出
$ busybox --list | head -20
[
[[
ash
awk
base64
basename
cat
chattr
chgrp
chmod
chown
chroot
clear
cmp
cp
cpio
cut
date
...

Applet 优先级

当系统中同时存在 BusyBox Applet 和完整版命令时:

# 查看命令来源
$ which ls
/bin/ls                    # 可能是 GNU ls 或 BusyBox 符号链接

$ ls --version
ls (GNU coreutils) 8.32    # GNU 版本
# 或
BusyBox v1.36.1 (...)      # BusyBox 版本

# BusyBox Applet 优先级:
# 1. PATH 中的完整命令(如 /usr/bin/ls)
# 2. BusyBox 符号链接(如 /bin/ls -> busybox)
# 3. busybox <applet> 显式调用

1.3 设计哲学

1.3.1 极简主义

BusyBox 的核心设计原则是**“够用就好”**:

// BusyBox 源码中的典型实现风格
// 以 cat 命令为例 (simplified)
static int cat_main(int argc, char **argv)
{
    int fd;
    
    // 简单直接的实现
    if (argc == 1) {
        // 读取 stdin
        bb_copyfd_eof(STDIN_FILENO, STDOUT_FILENO);
    } else {
        while (*++argv) {
            fd = open(*argv, O_RDONLY);
            if (fd < 0) {
                bb_perror_msg("can't open '%s'", *argv);
                continue;
            }
            bb_copyfd_eof(fd, STDOUT_FILENO);
            close(fd);
        }
    }
    return 0;
}

1.3.2 代码复用

大量公共函数被提取为共享库:

libbb/
├── bb_cat.c          # cat 实现
├── bb_copyfd.c       # 文件描述符复制
├── bb_getopt.c       # 参数解析
├── bb_mkpath.c       # 路径创建
└── ...

1.3.3 选项兼容性

BusyBox 尽量保持与 GNU 工具兼容,但有意简化:

# BusyBox 支持的典型选项
$ busybox ls -la /tmp
# 等价于 GNU ls -la /tmp

# BusyBox 特有的选项
$ busybox ls --color=auto   # 部分 Applet 支持

# BusyBox 不支持的选项(刻意简化)
$ busybox ls --author        # 不支持
$ busybox ls --time-style=  # 不支持

1.4 与 GNU 工具链对比

1.4.1 功能对比

方面BusyBoxGNU Coreutils
二进制大小1-3MB(全部)10-50MB(分散)
功能完整性子集(80% 常用功能)完整(100%)
选项支持简化版完整版
性能足够更优
可移植性极佳良好
依赖无(静态编译时)glibc 等
许可证GPLv2GPLv3

1.4.2 详细差异示例

ls 命令对比

# GNU ls 完整输出
$ ls --format=long --time-style=full-iso /tmp
drwxrwxrwt 2 root root 4096 2024-01-01 10:00:00.000000000 +0800 .

# BusyBox ls 输出
$ busybox ls -l /tmp
drwxrwxrwt    2 root     root         4096 Jan  1 10:00 .

sed 命令对比

# GNU sed 支持扩展正则
$ echo "hello" | sed -E 's/(hel)lo/\1p/'
helpp

# BusyBox sed 基本兼容,但部分高级特性缺失
$ echo "hello" | busybox sed -E 's/(hel)lo/\1p/'
helpp
# 注:BusyBox sed 对 -E 支持取决于编译选项

# GNU sed 支持的 in-place 编辑
$ sed -i 's/old/new/g' file.txt      # GNU
$ sed -i 's/old/new/g' file.txt      # BusyBox(兼容)

grep 命令对比

# GNU grep 完整选项
$ grep -P '\d+' file.txt             # PCRE 支持
$ grep --color=auto "pattern" file   # 高亮显示

# BusyBox grep(不支持 -P)
$ busybox grep -E '[0-9]+' file.txt  # 使用扩展正则替代
$ busybox grep "pattern" file        # 基本功能

1.4.3 选择建议

场景推荐原因
嵌入式设备BusyBox体积小,资源占用少
容器基础镜像BusyBox/Alpine快速启动,安全攻击面小
开发环境GNU功能完整,调试方便
生产服务器GNU性能和功能保障
系统恢复盘BusyBox单一二进制,易于部署

1.5 适用场景

1.5.1 嵌入式 Linux 系统

# 典型的嵌入式系统 rootfs
/
├── bin/
│   ├── busybox          # 主二进制
│   ├── sh -> busybox    # 符号链接
│   ├── ls -> busybox
│   └── ...              # 其他符号链接
├── etc/
│   ├── inittab          # BusyBox init 配置
│   └── init.d/
│       └── rcS          # 启动脚本
├── lib/                 # 动态库(静态编译时可为空)
├── proc/
├── sys/
└── dev/

1.5.2 Docker/容器基础镜像

# 基于 BusyBox 的极小镜像
FROM scratch
COPY busybox /busybox
RUN ["/busybox", "mkdir", "-p", "/bin", "/tmp", "/proc", "/sys", "/dev"]
RUN for cmd in sh ls cat echo cp mv rm mkdir; do \
        ["/busybox", "ln", "-s", "/busybox", "/bin/$cmd"]; \
    done
CMD ["/bin/sh"]

构建后镜像大小仅约 1-3MB

1.5.3 系统恢复/救援盘

# 创建最小恢复环境
$ mkdir -p rescue/{bin,sbin,etc,proc,sys,dev,tmp}
$ cp /bin/busybox rescue/bin/
$ cd rescue/bin
$ for cmd in sh ls cat mount umount fsck reboot; do
    ln -s busybox $cmd
  done

# 打包为 initramfs
$ cd ../..
$ find rescue | cpio -o -H newc | gzip > rescue.cpio.gz

1.5.4 网络设备/路由器固件

OpenWrt、DD-WRT 等路由器固件广泛使用 BusyBox:

OpenWrt 系统架构:
┌─────────────────────────────────┐
│          用户空间                │
│  ┌───────────────────────────┐  │
│  │        BusyBox            │  │
│  │  ash, ls, cat, wget...    │  │
│  └───────────────────────────┘  │
│  ┌───────────────────────────┐  │
│  │      应用程序              │  │
│  │  iptables, dnsmasq...     │  │
│  └───────────────────────────┘  │
├─────────────────────────────────┤
│          Linux 内核              │
├─────────────────────────────────┤
│          硬件平台                │
└─────────────────────────────────┘

1.6 BusyBox 版本与许可

版本历史

版本系列发布年份主要变化
0.x1999-2004C 语言重写,功能扩展
1.02005首个稳定版
1.202012改进 ash,新增 Applet
1.302019改进 musl 支持
1.362023改进安全特性
1.37+2024+持续维护

许可证

BusyBox is licensed under the GNU General Public License version 2 (GPLv2).

https://www.gnu.org/licenses/old-licenses/gpl-2.0.html

注意事项

  • 静态链接 BusyBox 的程序必须提供源码或源码获取方式
  • 商用嵌入式设备需遵守 GPLv2 要求
  • 动态链接不触发 GPL 传染性

1.7 安装 BusyBox 的预编译版本

大多数 Linux 发行版提供预编译的 BusyBox 包:

# Ubuntu/Debian
$ sudo apt install busybox

# CentOS/RHEL
$ sudo yum install busybox

# Arch Linux
$ sudo pacman -S busybox

# Alpine Linux(默认已安装)
$ apk add busybox

# 验证安装
$ busybox --help
BusyBox v1.36.1 (Ubuntu 1:1.36.1-1ubuntu1) multi-call binary.
...

提示:预编译版本通常包含大多数常用 Applet,但可能缺少某些可选功能。如需自定义功能,请参考第 2 章从源码编译。


1.8 本章小结

要点说明
Applet每个 Unix 命令对应一个 BusyBox Applet
设计哲学极简、够用、可裁剪
与 GNU 对比功能子集,体积优势明显
适用场景嵌入式、容器、恢复盘、网络设备
版本推荐使用 1.36+ 稳定版

扩展阅读


下一章: 第 2 章 — 编译安装