file
file 用于判断文件的实际类型。Linux 不靠扩展名认类型,.txt 结尾的可以是张图片,没有后缀的可以是可执行文件 —— file 读的是内容。
file [选项] 文件...输出格式是
文件名: 类型描述文件不存在或没有读权限时也会照常输出一行,说明是哪种错误
file 按顺序做三类测试,第一个命中的就是结果:
- 文件系统测试:调
stat,先分出目录、软链接、设备文件、空文件这些不用看内容就能判定的类型 - 魔数测试:读文件开头的若干字节,拿去和特征库比对。特征库是
/usr/share/misc/magic.mgc一类的编译产物,PNG 开头是89 50 4E 47、ELF 开头是7F 45 4C 46,都记在里面 - 语言测试:前两步都不匹配就当文本处理,进一步猜字符编码,以及是不是某种脚本或源码
判断依据全在内容里,所以改扩展名骗不过它,但反过来,故意伪造开头字节也能骗过它
| 选项 | 说明 |
|---|---|
-b |
只输出类型,不带文件名前缀(brief) |
-i |
输出 MIME 类型而不是描述文字(mime) |
--mime-type |
只输出 MIME 的类型部分,不带字符集 |
-L |
跟随软链接,报告目标文件的类型 |
-z |
顺带看压缩包内部的内容类型 |
-s |
读块设备、字符设备的内容,不止报告「是个设备」 |
-f <文件> |
从文件里逐行读要检查的路径 |
--extension |
输出该类型常见的扩展名 |
-k |
不在第一次命中后停下,把所有匹配都列出来 |
1. 基本判断
file note.md logo.png run.sh输出:
note.md: ASCII textlogo.png: PNG image data, 800 x 600, 8-bit/color RGBA, non-interlacedrun.sh: Bourne-Again shell script, ASCII text executable2. 扩展名不可信
mv logo.png logo.txtfile logo.txt输出:
logo.txt: PNG image data, 800 x 600, 8-bit/color RGBA, non-interlaced3. 拿 MIME 类型
file -i note.mdfile --mime-type -b note.md输出:
note.md: text/plain; charset=us-asciitext/plain脚本里做分支判断用
--mime-type -b,输出干净、好比较
4. 看可执行文件的细节
file /bin/ls输出:
/bin/ls: ELF 64-bit LSB pie executable, x86-64, dynamically linked,interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=..., stripped一行里能读出位数、动态还是静态链接、有没有被 strip
stripped意味着符号表已经去掉,这种二进制用 gdb 调试是看不到函数名的,见 gdb
5. 批量检查
find . -type f -exec file {} +file -f paths.txt
-exec ... +会把多个路径攒到一条命令里,比一个文件起一次进程快得多,见 find
man fileman 5 magic(特征库的格式)