Linux 文件属性

最后更新:
阅读次数:

概览

首先,我们先来了解一下 ls 命令的一些参数!

# -l 查看一个文件的详细属性
$ ls -l

# -h 查看一个文件的详细属性,但是文件大小会以一种更人性化的形式显示
$ ls -lh

# -i 显示每个文件的 inode 号
$ ls -i

当我们直接使用上面参数的组合时(ls -hil),就可以看到指定目录下文件的较详细的属性了。

# 使用 ls -ilh 命令后,那一行一行的字段是什么意思呢?
# 关键字:inode、文件类型、权限、硬链接、用户、用户组

+-inode number
|
| +-permissions that apply to the owner
| |
| | +-permissions that apply to all other users
| | |
| | | +-number of hard links
| | | |
| | | | +-the group that the group permissions applies to
| | | | |
| | | | | +-last modification date and time
__|__ _|_ _|_ | __|__ ________|_______
38729 drwxr-xr-x 2 percy staff 46K 2017-11-04 16:58 test1
_ ___ _____ ___ _____
| | | | |
| | | | +-file name
| | | |
| | | +-file size
| | |
| | +-file owner
| |
| +-permissions that apply to users who are members of the group
|
+-file type

inode

文件有文件名与数据,这在 Linux 上被分成两个部分:用户数据(user data)与元数据(metadata)。用户数据(即文件数据块 - data block),是记录文件真实内容的地方;而元数据则是文件的附加属性,如文件大小、创建时间、文件所有者等信息。

在 Linux 文件系统中,inode 是一种用来描述文件对象(比如一个文件或一个目录)的数据结构。每个 inode 都储存着对应文件的元数据和文件在磁盘上的位置信息,但没有储存文件的文件名。因为元数据中的 inode 号(inode number)才是文件的唯一标识而非文件名。文件名仅是为了方便人们的记忆和使用,系统或程序实际上是通过 inode 号寻找正确的文件数据块。

文件类型

# ls 命令中的 file type 字段下各字符所代表的文件类型
* : regular file
d : directory
c : character device file
b : block device file
s : local socket file
p : named pipe
l : symbolic link

权限、用户与用户组

  • Linux 通过用户与用户组来实现对文件访问、设备使用的控制。

  • 每一个文件对应三种类型的用户,每一种类型的用户对应三种访问权限

  • 三种文件权限:

    • 可读
    • 可写
    • 可执行
  • 三种类型的用户:

    • 用户:文件所有者
    • 用户组:文件所属用户组下的所有用户
    • 其它用户

硬链接与软链接

为解决文件的共享使用,Linux 系统引入了两种链接:硬链接 (hard link) 与软链接(又称符号链接,即 soft link 或 symbolic link)。链接为 Linux 系统解决了文件的共享使用,还带来了隐藏文件路径、增加权限安全及节省存储等好处。

硬链接

硬链接(hard link)本质上是一个有着与源文件相同的 inode 号、而文件名可能不同的文件。删除了源文件或更改了源文件的文件名并不会影响硬链接文件,但是更改了源文件的内容后,硬链接文件的内容也会随之改变!

在 Linux 中,文件和文件名是不同的东西,rm A 删除的只是 A 这个文件名,而 A 对应的数据块(文件)只有在 inode 节点链接数减少为 0 的时候才会被系统回收。

  • 硬链接存在以下几点特性:
    • 与源文件有相同的 inode 及 data block
    • 只能基于已存在的文件进行硬链接的创建
    • 不能交叉文件系统进行硬链接的创建
    • 不能基于目录进行硬链接的创建
    • 删除一个硬链接文件并不影响其它有相同 inode 号的文件

不能基于目录进行硬链接的创建是受限于文件系统的设计。现 Linux 文件系统中的目录均隐藏了两个特殊的目录:当前目录(.父目录(..。查看这两个特殊目录的 inode 号可知其实这两目录就是两个硬链接。若系统允许对目录创建硬链接,则会产生目录环

# 新建一个文件 test.txt,并写入一些内容
$ echo '12345' > test.txt

# 创建一个硬链接文件(使用 ln 或 link 命令)
$ ln test.txt hardlink.txt
$ link test.txt hardlink.txt

# 查看这两个文件的详细信息
$ ls -ilh

# total 16
# 8594132865 -rw-r--r-- 2 percy507 staff 6B Jan 10 13:14 hardlink.txt
# 8594132865 -rw-r--r-- 2 percy507 staff 6B Jan 10 13:14 test.txt

# 重命名源文件
$ mv test.txt 1.txt

# 再次查看这两个文件的详细信息
$ ls -ilh

# total 16
# 8594132865 -rw-r--r-- 2 percy507 staff 6B Jan 10 13:14 1.txt
# 8594132865 -rw-r--r-- 2 percy507 staff 6B Jan 10 13:14 hardlink.txt

软链接

软链接,又称符号链接,即 soft link 或 symbolic link。

软链接是一种特殊的文件,它有着自己的 inode 号以及用户数据块,其数据块中存放的内容是另一文件的路径名的指向。

  • 软链接存在以下几点特性:
    • 软链接有自己的文件属性及权限等
    • 可对不存在的文件或目录创建软链接
    • 可交叉文件系统进行软链接的创建
    • 可对文件或目录进行软链接的创建
    • 创建软链接时,链接计数不会增加
    • 删除软链接并不影响被指向的文件

若软链接指向的原文件被删除或文件绝对路径发生了变化(文件被放到其它目录或文件被重命名),那么软链接就不能正常访问原文件,则相关软链接被称为死链接。

可以基于某个软链接再进行软链接的创建。访问这个新建的软链接时,其解析过程是递归的。但需注意:在创建软链接时,源文件的路径指向最好使用绝对路径,因为使用相对路径创建的软链接在被移动后,该软链接文件将成为一个死链接。

# 新建一个文件 test.txt,并写入一些内容
$ echo '12345' > test.txt

# 创建一个软链接文件(使用 ln 命令,不能使用 link 命令)

# 基于源文件的相对路径
$ ln -s test.txt softlink1.txt

# 基于源文件的绝对路径(推荐)
$ ln -s /Users/percy507/linux/test.txt softlink2.txt

图解

linux-hard-link-and-soft-link.png

文件的时间属性

  • Windows 系统上的文件有 3 种与时间相关的属性:创建时间、最后访问时间与最后修改时间

  • Linux 系统上的文件有 3 种与时间相关的属性:最后访问时间、最后修改时间与最后改变时间(没有创建时间)

    • 最后访问时间(Access Time):读取一次文件的内容,会改变该时间
    • 最后修改时间(Modify Time):修改文件的内容,会改变该时间
    • 最后改变时间(Change Time):修改文件的属性或内容,会改变该时间
  • Mac 系统上的文件有 4 种与时间相关的属性:创建时间、最后访问时间、最后修改时间与最后改变时间

# touch 用来更改文件的访问时间与修改时间

# -t 一般只更改文件的最后修改时间与访问时间为指定时间,如果指定时间小于文件当前的创建时间,那么也会更改文件的创建时间至指定时间(仅限 Mac)
# 语法:touch -t YYYYMMDDhhmm file
$ touch -t 199901122356 file.txt

# 在 Mac 上,可以直接使用 SetFile 命令更改文件的创建时间
$ SetFile -d '12/31/1999 23:59:59' file.txt
$ SetFile -d "$(GetFileInfo -m test.txt)" file.txt
# Linux 中,stat 命令可以用来查看某个文件的属性信息(包括上面的 3 个时间)
$ stat -x file.txt

# 在 Mac 中,stat 命令也可以查看除过文件创建时间的那三种时间
# 但是,可以通过 `GetFileInfo` 命令查看文件的创建时间
$ GetFileInfo file.txt

# 在 Mac 中,还可以通过 stat 命令查看所有的时间
$ stat -f "Access (atime): %Sa%nModify (mtime): %Sm%nChange (ctime): %Sc%nBirth (Btime): %SB" file.txt

参考资料