Appearance
Linux 文件系统层次规范 FHS:软件安装的"黄金标准"
无论是通过 yum、apt 安装,还是手动编译源码,Linux 软件安装都必须遵循一套底层逻辑——Filesystem Hierarchy Standard (FHS)。
遵循这套规范,系统才能保持整洁,避免“依赖地狱”和文件混乱。本文将深入讲解可执行文件、库文件、配置文件和日志文件分别应该“住在哪里”。
核心原则:为什么不能随便放?
在 Windows 中,软件通常独占一个目录(如 C:\Program Files\MyApp)。但在 Linux 中,软件的文件是根据“用途”分散存储的:
- 可执行程序 集中存放(方便
$PATH查找) - 配置文件 集中存放(方便备份和管理)
- 库文件 共享存放(节省磁盘和内存)
一级目录速查表
| 目录 | 作用描述 | 关键特性 |
|---|---|---|
/ | 根目录,文件系统的起点 | 只包含子目录,不直接存放文件 |
/bin | 基本用户命令(启动时即需要的) | 指向 /usr/bin 的软链接(现代发行版) |
/sbin | 系统管理命令(如 fdisk, mount) | 仅 root 用户主要使用 |
/etc | 配置文件大本营 | 文本文件,几乎都是 ASCII 码 |
/usr | Unix System Resource:系统主要资源 | 可共享、只读,最大的目录 |
/var | Variable:变化的数据 | 日志、缓存、锁文件、Spool 文件 |
/tmp | 临时文件 | 重启通常会被清空 |
/proc | 虚拟文件系统,进程信息 | 存在于内存中(不占用硬盘) |
软件安装的“黄金四象限”
对于手动安装或开发一个应用到 Linux,请严格遵循以下四个维度的存放规范:
1. 可执行程序
| 类型 | 路径 | 示例 |
|---|---|---|
| 系统自带/包管理器 | /usr/bin/ | ls, grep, nginx |
| 本地手动编译 | /usr/local/bin/ | go1.22 (手动编译版) |
go install 安装 | ~/go/bin/ 或 $GOPATH/bin | go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest |
| 非系统关键服务 | /opt/<app>/bin/ | /opt/goland/bin/goland.sh |
💡 注意:
/bin通常是/usr/bin的软链接;不要将自己的脚本随意放入/usr/bin,请使用/usr/local/bin。
2. 配置文件
这是初学者最容易犯错的地方。
| 作用范围 | 路径 | 场景 |
|---|---|---|
| 全局配置 | /etc/<appname>/ | nginx.conf, ssh/sshd_config |
| 程序内部默认配置 | /usr/share/<app>/ | 通常不建议直接修改,应复制到 /etc 覆盖 |
| 用户配置 | ~/.config/<app>/ 或 ~/.<app>rc | ~/.bashrc, ~/.gitconfig |
3. 数据与日志
| 类型 | 路径 | 说明 |
|---|---|---|
| 运行时变量 (如 PID, Socket) | /run/<app>/ | 重启即消失 |
| 日志文件 | /var/log/<app>/ | 需要配置 logrotate 防止占满硬盘 |
| 缓存数据 | /var/cache/<app>/ | 可被删除而不影响功能 |
| 持久化数据 (数据库, 上传文件) | /var/lib/<app>/ | 比如 MySQL 的 /var/lib/mysql |
4. 静态资源与文档
| 类型 | 路径 |
|---|---|
| 文档/手册 | /usr/share/doc/<app>/ |
| 帮助手册 (Man Pages) | /usr/share/man/man1/ |
| 图标/桌面快捷方式 | /usr/share/applications/ (用于 GUI) |
实战:打包一个名为 myapp 的示例
假设你用 Go 写了一个守护进程叫 myapp,标准部署结构如下:
bash
# 1. 二进制文件(Go 编译产物)
/usr/local/bin/myapp
# 2. 配置文件
/etc/myapp/config.yaml
/etc/myapp/plugins/ # 子配置目录
# 3. systemd 服务文件(让开机自启)
/usr/lib/systemd/system/myapp.service
# 4. 日志(程序运行时自动生成)
/var/log/myapp/access.log
/var/log/myapp/error.log
# 5. 数据持久化(如果是个存储类应用)
/var/lib/myapp/database.db对应的 Go 程序读取配置示例
go
package main
import (
"fmt"
"os"
"gopkg.in/yaml.v3"
)
type Config struct {
Server struct {
Port int `yaml:"port"`
} `yaml:"server"`
Database struct {
Path string `yaml:"path"`
} `yaml:"database"`
}
func main() {
// 标准路径:/etc/myapp/config.yaml
configPath := "/etc/myapp/config.yaml"
data, err := os.ReadFile(configPath)
if err != nil {
// 降级读取本地开发配置
data, err = os.ReadFile("./config.yaml")
if err != nil {
panic(fmt.Sprintf("读取配置失败: %v", err))
}
}
var config Config
if err := yaml.Unmarshal(data, &config); err != nil {
panic(fmt.Sprintf("解析配置失败: %v", err))
}
fmt.Printf("Server port: %d\n", config.Server.Port)
}对应的 systemd 服务文件示例
ini
[Unit]
Description=My Go App
After=network.target
[Service]
Type=simple
User=myapp
Group=myapp
ExecStart=/usr/local/bin/myapp --config /etc/myapp/config.yaml
# 安全强化 - 限制文件系统访问
ReadWritePaths=/var/lib/myapp /var/log/myapp
ReadOnlyPaths=/etc/myapp
[Install]
WantedBy=multi-user.target针对 /opt 与 /usr/local 的选择建议
搜索该问题的读者经常纠结:我的第三方闭源软件放哪里?
| 场景 | 推荐目录 | 原因 |
|---|---|---|
源码编译 (go build + make install) | /usr/local | 这是 /usr 的本地补充,包管理器不会覆盖它。 |
| 解压即用 (Go 二进制单文件) | /opt 或 /usr/local/bin | /opt 适合大型静态软件包,单文件直接放 bin。 |
| 商业软件 (如 Goland, Datadog Agent) | /opt/<company> | FHS 明确指定 /opt 用于附加应用软件包。 |
| 发行版仓库没有的包 (如手动安装 Docker) | /usr/local/bin | 保持 /usr/bin 干净。 |
常见错误与纠正
- 错误:
go build -o ~/myapp然后把二进制放家目录,通过绝对路径调用。
- 后果:普通用户无法通过
sudo systemctl管理,环境变量 PATH 找不到。 - 纠正:生产环境使用
/usr/local/bin或/opt。
- 错误:将日志文件写在程序安装目录(如
/opt/myapp/logs/)下。
- 后果:日志轮转工具 (
logrotate) 默认监控/var/log;非特权用户运行时可能因权限不足导致无法写入日志。 - 纠正:严格遵守
/var/log。
- 错误:手动修改
/usr/share/下的默认配置。
- 后果:软件升级(覆盖
/usr/share)时,你的修改会丢失。 - 纠正:将配置复制到
/etc/或在/etc/中创建同名文件覆盖。
快速记忆口诀
二进制找
bin,配置找etc,日志找
var,静态找share,自己编译
local,大厂软件放opt。
查看当前系统的 FHS 实现
你可以通过以下命令查看你的 Linux 发行版是如何组织目录的:
bash
# 查看一级目录的挂载点
ls -lh /
# 检查 /bin 是否是软链接(现代发行版通常是)
file /bin
# 查看软件包安装的文件分别去了哪里(以 nginx 为例)
# 基于 RPM (CentOS/RHEL):
rpm -ql nginx
# 基于 DEB (Ubuntu/Debian):
dpkg -L nginx📚 参考文献:Filesystem Hierarchy Standard (FHS 3.0) — The Linux Foundation