简单看看 `file` 命令

简单的前言

虽然这里的日期是 2024-03-20,但是我写这篇博客的时候其实是 2025-02-18,来自我的计算机系统的讨论课材料. 如果你想知道一个文件的类型,那么你可能会用到 file 这个命令,file 会告诉你这个文件的类型,那么 file 是如何知道文件的类型的,或者说,系统中的文件如何告诉 file(或者任意一个想知道其类型的程序)自己的类型,文件把类型的信息放在哪里?

阅读手册

了解一个命令的第一个手段一般是 whatis / man / tldr.

man whatis 会告诉你,whatis 其实就来自 man:

Each manual page has a short description available within it. whatis searches the manual page names and displays the manual page descriptions of any name matched.

man file 会告诉你,file 这样检查文件的类型:

file tests each argument in an attempt to classify it. There are three sets of tests, performed in this order: filesystem tests, magic tests, and language tests. The first test that succeeds causes the file type to be printed.

  1. filesystem tests
    系统调用 stat, 根据其返回值判断文件的类型;stat 可以判断文件为空/文件类型是<sys/stat.h>中已定义的类型.
  2. magic tests
    检查文件头是否含有特定的 magic bytes. 例如,如果该文件的前五个字节对应的 ASCII 字符是"%PDF-",则判断为PDF文件. 若不存在任何 magic bytes, 则判断为文本文件,file 将继续判断其编码方式为 ASCII/UTF-8/…
  3. language tests
    通过关键字判断文件的语言,如从 main, struct, printf 推测该文本文件为 C 源文件.

近距离观察这个命令的执行流程的方式是 strace file foo.bar;你也可以把输出放到重定向到文件里,然后用 vim 查看它,以便进行关键字检索,如 strace file foo.bar &> strace.out; vim strace.out –>

欺骗 file

从 magic test 入手

fake pdf

从 language test 入手

C source file?

简单的结语

回答最开始的问题——file 通过 filesystem tests, magic tests, and language tests 得知文件的类型,文件通过文件头中的 magic byte / 文本编码 / 程序语言关键字来表达自己的类型.

Wish You a Nice Day!
Built with Hugo
Theme Stack designed by Jimmy