3、构建目录骨架:Linux根目录标准结构(FHS)、手动创建关键目录、自动化脚本实现。

说实话,很多做嵌入式Linux的朋友,一开始都会忽略根目录结构这件事。觉得不就是几个文件夹嘛,随便建建就行了。嗯,我以前也这么想。直到有一次,我帮客户排查一个系统启动异常的问题,折腾了两天,最后发现是某个关键目录权限不对,导致服务起不来。那感觉,真是一言难尽。

所以这一节,咱们就好好聊聊根目录骨架怎么搭。说白了,就是搞清楚FHS(Filesystem Hierarchy Standard)到底规定了什么,然后怎么用手动和自动的方式,把这事干得漂亮。

3.1 FHS到底在说什么?

FHS,全称是Filesystem Hierarchy Standard。它不是什么高深的理论,就是一套约定。大家约定好,哪个目录放什么东西,这样换一台机器,你也能快速找到配置文件、日志、可执行程序。

我个人的习惯是,把FHS的核心目录分成三类:

  • 启动必备的:/boot、/etc、/sbin、/bin、/lib、/dev
  • 运行时需要的:/proc、/sys、/tmp、/var、/run
  • 用户和应用相关的:/home、/root、/usr、/opt、/mnt、/media

你想想看,如果少了/boot,内核往哪放?没有/etc,系统配置怎么读?没有/dev,设备文件去哪找?所以,这些目录一个都不能少。

核心原则:嵌入式系统虽然可以裁剪,但FHS定义的关键目录结构,最好保持完整。否则,很多标准工具和脚本会直接报错。

3.2 手动创建关键目录

我记得刚开始做嵌入式Linux的时候,都是手动敲命令建目录。虽然现在有自动化脚本了,但手动建一次,能帮你深刻理解每个目录的用途。

下面是我常用的手动创建命令,咱们一条一条来看:

# 创建根目录下的标准目录
mkdir -p /rootfs/{bin,boot,dev,etc,home,lib,media,mnt,opt,proc,root,run,sbin,srv,sys,tmp,usr,var}

# 创建 /usr 下的子目录
mkdir -p /rootfs/usr/{bin,include,lib,local,sbin,share,src}

# 创建 /var 下的子目录
mkdir -p /rootfs/var/{cache,lib,lock,log,run,spool,tmp}

# 设置关键目录权限
chmod 755 /rootfs/root
chmod 1777 /rootfs/tmp
chmod 1777 /rootfs/var/tmp

这里有个细节要注意:/tmp和/var/tmp的权限是1777。那个1是粘滞位(sticky bit),意思是只有文件所有者才能删除自己的文件。我曾经见过有人忘了加这个,结果普通用户把别人的临时文件删了,导致程序崩溃。嗯,这种坑踩过一次就记住了。

小技巧:创建目录时,可以用-p参数自动创建父目录。比如mkdir -p /rootfs/usr/local/bin,如果/usr/local不存在,它会一并创建。

3.3 自动化脚本实现

手动建目录,一次两次还行。但如果你要批量制作多个rootfs,或者频繁重建系统,那就得靠脚本了。我一般会写一个create_rootfs.sh,把整个流程自动化。

下面是我在实际项目中用过的脚本,稍微简化了一下:

#!/bin/bash
# 文件名: create_rootfs.sh
# 功能: 自动化构建Linux根目录骨架

ROOTFS_DIR="/rootfs"

# 定义标准目录列表
DIRECTORIES=(
    "bin"
    "boot"
    "dev"
    "etc"
    "home"
    "lib"
    "media"
    "mnt"
    "opt"
    "proc"
    "root"
    "run"
    "sbin"
    "srv"
    "sys"
    "tmp"
    "usr"
    "var"
)

# 定义子目录结构(使用关联数组)
declare -A SUB_DIRS
SUB_DIRS["usr"]="bin include lib local sbin share src"
SUB_DIRS["var"]="cache lib lock log run spool tmp"

echo "开始构建根目录骨架..."
echo "目标路径: ${ROOTFS_DIR}"

# 创建主目录
for dir in "${DIRECTORIES[@]}"; do
    mkdir -p "${ROOTFS_DIR}/${dir}"
    echo "  [OK] 创建 /${dir}"
done

# 创建子目录
for parent in "${!SUB_DIRS[@]}"; do
    for sub in ${SUB_DIRS[$parent]}; do
        mkdir -p "${ROOTFS_DIR}/${parent}/${sub}"
        echo "  [OK] 创建 /${parent}/${sub}"
    done
done

# 设置特殊权限
chmod 755 "${ROOTFS_DIR}/root"
chmod 1777 "${ROOTFS_DIR}/tmp"
chmod 1777 "${ROOTFS_DIR}/var/tmp"

echo "根目录骨架构建完成!"
echo "目录总数: $(find ${ROOTFS_DIR} -type d | wc -l)"

这个脚本的好处是,你只需要改ROOTFS_DIR变量,就能把骨架建到任意路径下。而且它用了关联数组,扩展性很好。比如你想加一个/opt/myapp目录,直接在SUB_DIRS里加一行就行。

注意事项:脚本里没有处理/dev和/proc这些虚拟文件系统。它们需要在系统启动时由内核挂载,不能提前创建文件。如果你在构建阶段需要它们,可以用mount --bind临时挂载。

3.4 知识体系结构图

为了让你更直观地理解整个目录骨架的构建逻辑,我画了一张图。它展示了从FHS标准到手动创建,再到自动化脚本的完整流程。

根目录骨架构建知识体系 FHS标准(Filesystem Hierarchy Standard) 启动必备目录 运行时目录 用户/应用目录 /boot /etc /sbin /bin /lib /dev (系统启动必需) /proc /sys /tmp /var /run /home /root /usr /opt /mnt /media /srv 构建方式:手动创建 vs 自动化脚本(create_rootfs.sh) 完整的Linux根目录骨架

这张图把整个流程串起来了。从FHS标准出发,先理解目录分类,再具体到每个目录的用途,最后通过手动或自动方式构建出来。我个人觉得,这张图对初学者特别友好,能一眼看清全局。

3.5 避坑指南

最后,分享几个我踩过的坑:

  • 权限问题:/tmp和/var/tmp一定要设1777,否则很多程序会报“Permission denied”。
  • 符号链接:有些系统会把/bin、/sbin链接到/usr/bin、/usr/sbin。如果你要这么做,记得在脚本里加上ln -s命令。
  • 空目录:/proc、/sys、/dev在构建阶段是空的,这很正常。别担心,启动时内核会挂载。
  • 大小写敏感:Linux目录名是大小写敏感的。千万别把“/etc”写成“/ETC”,否则系统找不到配置文件。

嗯,这一节的内容就到这里。目录骨架搭好了,后面往里面填充文件系统、配置服务,就顺理成章了。

核心总结:FHS是根目录结构的“宪法”,手动创建能帮你理解细节,自动化脚本能提升效率。两者结合,才是最佳实践。