# 目录

  • 物理上,Linux 系统的文件可能储存在磁盘、内存等设备中;逻辑上,每个文件存储在目录中,而所有目录按上下层级、树形结构组成了目录树。
  • 目录树的根部称为根目录,即最上层目录。
  • 每个文件都有自己的存储路径,用于在目录树中定位它。

# 目录符号

Linux 系统提供了一些指向特定目录的符号:

符号 指向的目录
. 当前目录
.. 上一级目录
- 上一次所在的目录
~ 当前用户的家目录
~leo 指定用户的家目录

# 相关命令

# pwd

$ pwd             # 显示当前的工作目录(print working directory)

# cd

$ cd [dir]        # 切换到指定目录(change directory),不指定 path 则相当于 cd ~
     -            # 切换到上一次所在的目录
     ..           # 切换到上一级目录

# mkdir

$ mkdir <dir>...  # 创建一个目录(如果该目录已存在,则报错)
        -p        # 当该目录已存在时,不报错(可用于创建多层目录)
  • 例:
    mkdir dir1 dir2   # 创建多个同级目录
    mkdir -m 711 dir1 # 创建目录并分配权限,而不是默认权限
    

# rmdir

$ rmdir <dir>...      # 删除一个目录(如果该目录不为空,则报错)

# FHS

为了规范不同用户使用目录的习惯,Linux 基金会制定了文件系统层次化标准(Filesystem Hierarchy Standard ,FHS),它规定了根目录下应该有哪些目录、分别用于什么用途。

关于系统:

  • /boot :存储系统开机时需要的文件,比如 grub、内核文件。
  • /bin :存储系统的一些可执行文件。
  • /sbin :存储系统的一些重要的管理程序,只有 root 用户能使用。
  • /lib :存储系统的一些函数库、目标文件,供/bin、/sbin 目录下的程序调用。

软件使用的目录:

  • /usr :存储大部分软件的源文件,全称为 Unix Software Resource 。
    /usr/bin      # 存储软件的可执行文件
    /usr/include  # 存储 C/C++ 语言的头文件
    /usr/lib      # 存储软件的函数库、目标文件
    /usr/share    # 存储共享文件
    /usr/src      # 存储源代码
    /usr/local    # 存储用户自己安装的软件(是编译后的软件包,不是源代码),相当于 Windows 的 Programs Files 文件夹
    
  • /opt :安装一些第三方软件。
  • /etc :存储一些配置文件。
  • /run :存储某些软件运行时产生的临时文件,比如:sshd.pid、docker.sock 。采用 tmpfs 文件系统。
  • /srv :存储一些网络服务的数据文件。比如 WWW 服务会使用/srv/www 目录。
  • /var :存储一些经常变化的文件。
    /var/cache    # 供程序暂时存储一些文件
    /var/run      # 是指向 /run 的符号链接
    
    /var/log            # 存储各种日志文件
    
    /var/log/audit/*    # 内核进程 kauditd 的审计日志,记录了各种系统调用、文件访问
    /var/log/boot.log   # 开机引导的日志
    /var/log/dmesg      # 内核日志,可用 dmesg 命令查看
    /var/log/messages   # 一般的系统日志,来源于内核、应用程序
    
    /var/log/secure     # 用户的登录日志
    /var/log/wtmp       # 登录成功的日志、开机时刻
    /var/log/btmp       # 登录失败的日志
    
    /var/log/cron       # crond 定时任务的日志
    /var/log/firewalld  # 防火墙的日志
    /var/log/maillog    # 发送、接收邮件的日志
    

用户使用的目录:

  • /root :超级用户的主目录。
  • /home :普通用户的主目录,该目录下一般有与用户同名的文件夹。
  • /tmp :用于临时存储文件。
    • 该目录权限为 777 ,允许所有用户访问。不过每个用户创建的文件依然为普通权限。
    • 系统会定期清理 /tmp 目录,例如 CentOS 7 中:
      • systemd 每天执行一次定时任务,删除 /tmp 目录下超过 10 天没有被使用(包括 Access、Modify、Change)的文件。
      • 可以修改配置文件 /usr/lib/tmpfiles.d/tmp.conf ,用 x 排除删除指定的目录及其内容,用 X 排除删除指定的目录但不排除其内容。
      • 可以将平时要删除的文件移动到 /tmp 目录下,等待被系统自动清理,从而可以在误删时找回。

关于设备:

  • /dev :存储设备文件、socket 文件。
    /dev/null   # 一个特殊的字符设备文件,任何写入的数据都会被丢弃,不能读取到任何值。常用作垃圾箱
    /dev/zero   # 一个特殊的字符设备文件,任何写入的数据都会被丢弃,可以读取到无穷的 Null 值。常用于初始化文件
    
  • /media :用于挂载媒体设备,比如软盘、光盘(/media/cdrom)。
  • /mnt :用于暂时挂载设备、文件系统,比如光驱。
  • /proc :一个存储在 RAM 中的虚拟目录,包含一些关于系统信息的文件,它们不占磁盘空间。
  • /sys :一个存储在 RAM 中的虚拟目录,与 /proc 类似。

# /proc

:一个存储在 RAM 中的虚拟目录,包含一些由内核生成的文件(大小为 0、只读)。

  • 参考文档 (opens new window)
  • 通过这些文件可以与系统内核交互。
  • 其中的某些文件采用 ASCII 码,可以用 cat 直接查看其内容。

/proc 目录下的常用文件:

/proc/
├── <PID>/          # 一个虚拟目录,记录一个正在运行的进程的相关信息
│   ├── exe         # 一个符号链接,指向启动该进程的可执行文件
│   ├── comm        # 记录启动该进程的命令名
│   ├── cmdline     # 记录该进程的启动命令
│   ├── cwd         # 一个符号链接,指向该进程的工作目录
│   ├── environ     # 记录该进程的环境变量
│   ├── fd/         # 一个目录,包含一些符号链接(名字为文件描述符),指向该进程打开的文件
│   ├── root        # 一个符号链接,指向该进程的根目录
│   ├── maps        # 记录进程每块虚拟内存空间的信息
│   ├── smaps       # 记录进程每块虚拟内存空间的地址、用途,以及 Size、RSS、PSS、Swap 等大小
│   ├── stack       # 记录内核中堆栈的信息。它对应主线程的堆栈,而 task/<TID>/stack 对应其它线程的堆栈
│   ├── stat        # 记录该进程的当前状态。是一系列数字,可读性差。 ps 命令就是读取该信息
│   ├── statm       # 记录进程的总内存信息,比如 VIRT、RSS、SHR 大小。是一组数字,可读性差,且存在误差
│   ├── status      # 记录该进程的当前状态,可读性好
│   └── task/       # 一个目录,包含该进程创建的所有线程的虚拟目录
│       └── <TID>/  # 一个虚拟目录,记录一个正在运行的线程的相关信息
│           ├── cmdline
│           ├── comm
│           ├── exe
│           └── status
├── cpuinfo         # 记录 CPU 的硬件信息
├── meminfo         # 记录 MemTotal、Buffers、Slab 等各种内存的大小
├── devices         # 记录系统的所有设备名称(包括字符设备、块设备)
├── version         # 记录系统内核的版本
├── swaps           # 记录 swap 分区的信息
└── sys/            # 一个与内核相关的目录
  • 例:

    [[email protected] ~]# file /proc/1/exe
    /proc/1/exe: symbolic link to '/usr/lib/systemd/systemd'
    [[email protected] ~]# cat /proc/1/comm
    systemd
    [[email protected] ~]# cat /proc/1/cmdline    # 显示启动命令时会去掉空格
    /usr/lib/systemd/systemd--switched-root--system--deserialize22
    
  • /proc/self 目录是一个特殊的符号链接,指向当前查询该目录的进程的 /proc/<PID> 目录。如下:

    [[email protected] ~]# ls -lh /proc/self
    lrwxrwxrwx. 1 root root 0 Nov 12 06:10 /proc/self -> 15030              # 每次执行 ls 命令都是创建一个子进程,因此查询到的 PID 会变化
    [[email protected] ~]# ls -lh /proc/self
    lrwxrwxrwx. 1 root root 0 Nov 12 06:10 /proc/self -> 15031
    [[email protected] ~]# ls -lh /proc/self
    lrwxrwxrwx. 1 root root 0 Nov 12 06:10 /proc/self -> 15032
    [[email protected] ~]# cat /proc/self/cmdline
    cat/proc/self/cmdline
    
  • 例:

    [[email protected] ~]# cat /proc/1/smaps
    55d734e25000-55d734f89000 r-xp 00000000 fd:01 12008                      /usr/lib/systemd/systemd
    Size:               1424 kB
    Rss:                 848 kB
    Pss:                 848 kB
    Shared_Clean:          0 kB
    Shared_Dirty:          0 kB
    Private_Clean:       848 kB
    Private_Dirty:         0 kB
    Referenced:          848 kB
    Anonymous:             0 kB
    AnonHugePages:         0 kB
    Swap:                  0 kB
    KernelPageSize:        4 kB
    MMUPageSize:           4 kB
    Locked:                0 kB
    VmFlags: rd ex mr mp me dw sd
    55d735189000-55d7351ac000 r--p 00164000 fd:01 12008                      /usr/lib/systemd/systemd
    Size:                140 kB
    ...
    
    • 第一行各个字段的含义:
      • 55d734e25000-55d734f89000 表示这块虚拟内存空间的地址范围。
      • r-xp 表示读写权限。
      • 00000000 表示这块虚拟内存空间通过 mmap() 映射到文件中的的起始地址。对于匿名映射,该值为一串 0 。
      • fd:01 表示映射文件所在的主设备号、次设备号。对于匿名映射,该值为 00:00 。
      • 12008 表示映射文件的 inode 编号。对于匿名映射,该值为 0 。
      • /usr/lib/systemd/systemd 表示映射的文件名。对于匿名映射,取值 [heap][stack] 表示这块虚拟内存空间用于堆、栈。
    • 每一块虚拟内存空间的下方,记录了 Size、Rss、Pss、Swap 等大小。
      • 常驻的物理内存 RSS 分为共享内存和私有内存,即 RSS = Shared_Clean + Shared_Dirty + Private_Clean + Private_Dirty