English
Linux Filesystem Hierarchy Standard FHS: The "Gold Standard" for Software Installation
Whether through yum,apt Whether installing packages or manually compiling source code, Linux software installation must follow a set of underlying principles—Filesystem Hierarchy Standard (FHS).
Only by following this specification can the system stay clean and avoid "dependency hell" and file clutter. This article will explain in depth where executable files, library files, configuration files, and log files should each "live."
Core Principle: Why Can’t It Be Placed Casually?
In Windows, software usually has its own directory (such as C:\Program Files\MyApp). But in Linux,The software's files are stored separately according to "purpose.":
executable program Centralized storage (convenient
$PATHSearch)Configuration file Centralized storage (convenient for backup and management)
Library file Shared storage (saves disk and memory)
First-Level Directory Quick Reference Table
| Table of Contents | Function description | Key Features |
|---|---|---|
/ | Root directory, the starting point of the file system | Contains only subdirectories and does not directly store files. |
/bin | Basic user commands (required at startup) | point to /usr/bin the symbolic link (modern distributions) |
/sbin | System management commands (such as fdisk,mount) | only root The user mainly uses |
/etc | Configuration File Base Camp | Text files, almost all of which are ASCII code. |
/usr | Unix System Resource: Main system resources | Shareable, read-only, the largest directory |
/var | Variable: Changing data | Logs, cache, lock files, spool files |
/tmp | Temporary file | It is usually cleared after a restart. |
/proc | Virtual file system, process information | Exists in memory (does not take up disk space) |
The "Golden Four Quadrants" of Software Installation
For manually installing or developing an application on Linux, please strictly follow the storage specifications in the following four dimensions:
1. Executable program
| Type | path | Example |
|---|---|---|
| System built-in/package manager | /usr/bin/ | ls,grep,nginx |
| Local manual compilation | /usr/local/bin/ | go1.22(Manual compilation version) |
go install Install | ~/go/bin/ or $GOPATH/bin | go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest |
| Non-system-critical service | /opt/<app>/bin/ | /opt/goland/bin/goland.sh |
💡 Note
/bin Usually /usr/bin the symbolic link of; do not casually put your own scripts into /usr/bin, please use /usr/local/bin.
2. Configuration file
This is where beginners are most likely to make mistakes.
| Scope of effect | Path | Scene |
|---|---|---|
| Global Configuration | /etc/<appname>/ | nginx.conf,ssh/sshd_config |
| Internal default configuration of the program | /usr/share/<app>/ | It is usually not recommended to modify it directly; you should copy it to /etc Coverage |
| User configuration | ~/.config/<app>/ or ~/.<app>rc | ~/.bashrc,~/.gitconfig |
3. Data and Logs
| Type | path | Description |
|---|---|---|
| runtime variable(e.g., PID, Socket) | /run/<app>/ | Disappears upon restart |
| log file | /var/log/<app>/ | Configuration required logrotate Prevent the hard disk from filling up |
| Cache data | /var/cache/<app>/ | Can be deleted without affecting functionality |
| Persistent data(database, upload file) | /var/lib/<app>/ | For example, MySQL's /var/lib/mysql |
4. Static Resources and Documentation
| Type | path |
|---|---|
| Documentation/Manual | /usr/share/doc/<app>/ |
| Help Manual(Man Pages) | /usr/share/man/man1/ |
| Icon/Desktop shortcut | /usr/share/applications/(used for GUI) |
Hands-on: Package an item named myapp example of
Suppose you wrote a daemon in Go called myapp, the standard deployment structure is as follows:
bash
# 1. Binary file (Go build artifact)
/usr/local/bin/myapp
# 2. Configuration file
/etc/myapp/config.yaml
/etc/myapp/plugins/ # Sub-configuration directory
# 3. systemd service file (make it start on boot)
/usr/lib/systemd/system/myapp.service
# 4. Logs (automatically generated when the program runs)
/var/log/myapp/access.log
/var/log/myapp/error.log
# 5. Data persistence (if it is a storage-type application)
/var/lib/myapp/database.dbExample of the corresponding Go program reading configuration
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() {
// Standard path: /etc/myapp/config.yaml
configPath := "/etc/myapp/config.yaml"
data, err := os.ReadFile(configPath)
if err != nil {
// Fall back to reading the local development configuration
data, err = os.ReadFile("./config.yaml")
if err != nil {
panic(fmt.Sprintf("failed to read configuration: %v", err))
}
}
var config Config
if err := yaml.Unmarshal(data, &config); err != nil {
panic(fmt.Sprintf("failed to parse configuration: %v", err))
}
fmt.Printf("Server port: %d\n", config.Server.Port)
}corresponding systemd Service file example
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
# Security hardening - Restrict filesystem access
ReadWritePaths=/var/lib/myapp /var/log/myapp
ReadOnlyPaths=/etc/myapp
[Install]
WantedBy=multi-user.targetTargeting /opt and /usr/local Selection suggestions
Readers searching for this question often struggle with: Where should I put my third-party closed-source software?
| Scene | Recommended catalog | Reason |
|---|---|---|
Source code compilation (go build+make install) | /usr/local | This is /usr local supplement to it; the package manager will not overwrite it. |
| Unzip and use(Go single-file binary) | /opt or /usr/local/bin | /opt Suitable for large static software packages; a single file can be placed directly.bin. |
| commercial software(e.g., GoLand, Datadog Agent) | /opt/<company> | FHS explicitly specifies /opt Used to attach application software packages. |
| Packages not available in the distribution repository(e.g., manually install Docker) | /usr/local/bin | Maintain /usr/bin Clean. |
Common Errors and Corrections
Error:
go build -o ~/myappThen put the binary in the home directory and invoke it via an absolute path.Consequences: Regular users cannot pass
sudo systemctlManagement, the environment variable PATH cannot be found.Correct: For use in production environment
/usr/local/binor/opt.Error: Write the log file in the program installation directory (e.g.,
/opt/myapp/logs/) below.Consequences Log rotation tool (
logrotate) default monitoring/var/log; When running as an unprivileged user, insufficient permissions may prevent log writing.Correct: Strictly comply
/var/log.Error: Manual modification
/usr/share/default configuration under.consequences: Software upgrade (overwrite
/usr/sharewhen), your changes will be lost.Correct: Copy the configuration to
/etc/or in/etc/Create a file with the same name in it to overwrite.
Quick memorization mnemonic
binary search bin, find configuration etc,
Log search var, static search share,
Compile it yourself.local, big tech software release opt.
View the current system's FHS implementation
You can use the following command to see how your Linux distribution organizes directories:
bash
# View the mount point of the top-level directory
ls -lh /
# Check whether /bin is a symlink (usually it is in modern distributions)
file /bin
# Check where the files installed by a package go (using nginx as an example)
# Based on RPM (CentOS/RHEL):
rpm -ql nginx
# Based on DEB (Ubuntu/Debian):
dpkg -L nginx📚References Filesystem Hierarchy Standard (FHS 3.0) — The Linux Foundation