file 是一个 Linux 基础命令,用于探测文件的真实类型。在 Linux 中,文件的扩展名(如 .txt)并不完全可信,file 命令通过检查文件内容来准确判断其类型。

file 命令的判断过程分为以下三步,按顺序进行直到得出结果:
stat 系统调用,检查文件是否为空,或者是否为目录、符号链接、套接字(socket)、管道(FIFO)等特殊文件。file 会读取文件内容,查找特定的“魔法数字”。例如,一个 ELF 可执行文件的头部会有一个固定的十六进制数字 7F 45 4C 46,file 通过识别它来判断这是一个二进制程序。file 会尝试分析其内容。例如,检查文件开头是否有 #!(如 #!/bin/bash 表示是 Shell 脚本),或查找 struct、class 等关键字来判断是否为 C/C++ 代码。命令语法:
file [选项] [文件名...]
常用参数:
| 参数 | 描述 |
|---|---|
-b | 不显示文件名,只显示结果。 |
-i | 输出文件的 MIME 类型(如 text/plain; charset=utf-8)。 |
-L | 如果目标文件是软链接,则显示链接所指向的源文件类型。 |
-z | 尝试查看压缩文件(如 .gz、.bz2)的内部信息。 |
-s | 读取块设备或字符设备文件。常用于查看磁盘分区的文件系统类型(需 root 权限)。 |
-f | 从指定文件中读取待检查的文件名列表(每行一个)。 |
为了方便理解,这里准备了一些常见的使用场景:
1. 基础用法:查看单个文件类型
这是 file 最直接的使用方式,它会输出文件名和类型。
$ file a.txt a.txt: UTF-8 Unicode text
这里显示 a.txt 是一个 UTF-8 编码的文本文件,而不是依据其 .txt 扩展名。
2. -b:只看结果,不显示文件名
如果只需要类型信息,可以使用 -b 参数(brief 模式)。
$ file -b a.txt UTF-8 Unicode text
这在脚本处理输出时特别有用。
3. -i:以 MIME 格式输出
有时你需要更标准的类型描述,比如在编写程序时判断文件是否为文本。
$ file -i a.txt a.txt: text/plain; charset=utf-8
这样输出结果就是标准的 MIME 类型。
4. -L:追踪符号链接
Linux 中的软链接就像一个快捷方式。不加 -L 时,file 显示它是一个链接;加上 -L 则会告诉你它指向的那个文件是什么。
# 不加 -L:显示这是一个指向 /usr/share/dict/words 的符号链接 $ file /usr/share/dict/words /usr/share/dict/words: symbolic link to ../share/dict/words # 加 -L:直接显示目标文件的类型 $ file -L /usr/share/dict/words /usr/share/dict/words: ASCII text
/usr/share/dict/words 通常是 american-english 文件的链接,因此 -L 会直接报告它是文本文件。
5. 结合通配符:批量查看
file 可以配合 * 通配符,一次性查看当前目录下所有文件的类型。
$ file * abc.sh: Bash script, ASCII text executable test.zip: Zip archive data, at least v2.0 to extract docs/: directory
file 命令还能在系统故障排查时派上用场。
场景一:查看磁盘分区文件系统
当不确定 /dev/sda1 是 ext4 还是 xfs 时,可以使用 -s 参数直接读取设备文件(通常需要 sudo)。
$ sudo file -s /dev/sda1 /dev/sda1: Linux rev 1.0 ext4 filesystem data, UUID=...
.tar.gz 文件里面是什么?不用解压,用 -z 参数查看:$ file -z ubuntu-22.04.iso.gz ubuntu-22.04.iso.gz: ISO 9660 CD-ROM filesystem data (gzip compressed data, from Unix)
file 命令的核心理念就是无视扩展名,只相信文件内容。一个名为 photo.jpg 的文件,如果内容是 rm -rf /,file 会准确地告诉你它是一个脚本文件。file 可能会将其判断为 data 而不是 text。这是因为样本太少,无法安全地判定为文本。