Linux的file命令:别再被文件后缀名骗了,一条命令看穿真实格式

      发布在:后端技术      评论:0 条评论

先说个真事

前两天帮朋友搞服务器,他传了个 youxiang.zip 上来,1.7G,挺大一个包。然后他跑 unzip youxiang.zip,直接报错:

image

End-of-central-directory signature not found.

他问我:"是不是文件损坏了?要不要重新传?"

我说你先别急,跑一下这个:

file youxiang.zip

输出:

youxiang.zip: gzip compressed data, from Unix

得,这玩意儿压根就不是zip,是个tar.gz,就是后缀名写错了。

tar xzf youxiang.zip

完事,两秒钟搞定。

你看,要是不知道有 file 这命令,可能折腾半天重新下载、校验md5、换工具……全是无用功。


file命令到底是干嘛的

一句话说清楚:它告诉你一个文件到底是什么格式。

注意,它不看后缀名。你就算把 test.mp4 改名成 test.txt,它照样告诉你这是视频文件。

为啥?因为Linux压根就不靠后缀名认文件。后缀名纯粹是给人看的,系统不care。这跟Windows不一样,Windows把 .txt 改成 .exe 双击真会尝试执行。Linux不会,它看的是文件内容。


它怎么判断的?

靠的是魔数(Magic Number)

就是文件开头那几个字节。每种格式都有固定的"暗号":

  • ZIP文件开头是 PK(0x50 0x4B)
  • gzip文件开头是 1f 8b
  • JPEG开头是 ff d8 ff
  • PDF开头是 %PDF

file 命令就是去读文件头部,跟内置的魔数库比对,匹配上了就告诉你结果。

你可以看看这个魔数库在哪:

file --version
# 一般魔数文件在 /usr/share/misc/magic 或 /usr/share/file/magic.mgc


基本用法

没啥好说的,就是:

file 文件名

几个例子你感受一下:

$ file photo.jpg
photo.jpg: JPEG image data, JFIF standard 1.01, resolution (DPI), density 72x72

$ file deploy.sh
deploy.sh: Bourne-Again shell script, ASCII text executable

$ file youxiang.zip
youxiang.zip: gzip compressed data, from Unix

$ file index.html
index.html: HTML document, UTF-8 Unicode text

$ file mysql
mysql: ELF 64-bit LSB executable, x86-64, dynamically linked

最后那个是二进制可执行文件,也能识别出来。


几个实用参数

-b:别废话,只说类型

默认输出会带上文件名,有时候你写脚本不需要文件名:

$ file -b youxiang.zip
gzip compressed data, from Unix

干净。

-i:输出MIME类型

写Web相关的可能用得上:

$ file -i youxiang.zip
youxiang.zip: application/gzip; charset=binary

$ file -i photo.jpg
photo.jpg: image/jpeg; charset=binary

-z:看压缩包里是啥

这个挺有意思,它会尝试解压一层再看:

$ file -z youxiang.tar.gz
youxiang.tar.gz: POSIX tar archive (gzip compressed data)

批量识别

file *
file *.zip

直接通配符,目录下所有文件一口气全识别。


实际踩坑场景

场景一:下载下来是个HTML

用wget或者curl下文件,有时候URL重定向了或者404了,你存下来的其实是个网页:

$ file download.zip
download.zip: HTML document, UTF-8 Unicode text

这时候你打开一看,好家伙,是个404页面或者登录页面。重新下就完了。

场景二:FTP传输用了ASCII模式

这个坑我见过太多次了。FTP默认是ASCII模式传文本,你传个二进制文件用ASCII模式,文件就废了:

$ file backup.tar.gz
backup.tar.gz: data

输出一个 data,说明文件已经损坏,认不出格式了。重传,记得 binary 模式。

场景三:后缀名全是乱的

有些项目里文件命名一塌糊涂,.zip 里混着 .rar.7z.tar.gz,一个个试太烦了:

for f in *.zip; do echo "$f: $(file -b $f)"; done

一行命令全列出来,哪个是假的zip一目了然。

场景四:判断是不是文本文件

写脚本的时候经常需要判断:

if file -b "$1" | grep -q "text"; then
    echo "是文本文件"
else
    echo "是二进制文件"
fi


跟其他命令对比一下

需求用什么
看文件真实格式file
看文件头部十六进制xxd file | headhexdump -C file | head
看文件编码file -ichardet
看图片详细信息exiftoolidentify(ImageMagick)

有时候 file 识别不出来,输出个 data,你可以用 xxd 看头部字节自己判断:

xxd youxiang.zip | head -3

开头是 1f8b 就是gzip,504b 就是zip,5261 就是rar。手动认魔数,土办法但管用。


最后说两句

file 这命令太基础了,基础到很多人装完系统从来没敲过。但你真遇到"这文件怎么解不开""这文件怎么打不开"的时候,第一反应就应该是:

file 文件名

先搞清楚它到底是啥,再决定用什么工具。别对着一个tar.gz文件反复 unzip,那是在跟系统较劲,系统不会赢,但你会浪费十分钟。

记住:Linux下后缀名就是个装饰,file命令说的才是真话。


相关文章

几条命令快速确认 Linux 系统中是否已安装 Apache、Nginx 等 Web 服务,涵盖包管理查询、进程检查、服务状态、配置文件及端口监听等实用方法。

Nginx 启动时没有任何错误日志就悄悄退出?本文通过宝塔面板的真实案例,详解如何使用 strace 命令追踪系统调用,精准定位因缺少 cjson.so 库导致的 Nginx 启动失败。

本文全面整理了WSL必知必会的核心命令,涵盖安装配置、发行版管理、系统迁移、性能优化及高级调试等全场景。从基础到进阶,手把手教你用WSL在Windows上打造高效Linux开发环境。附WSL2最新特性(内核6.18 LTS、GPU加速、zswap内存优化)与常见问题排查。适合Windows开发者、DevOps工程师及Linux新手收藏使用

一、查看Linux内核版本命令(两种方法):1、cat /proc/version2、uname -a二、查看Linux系统版本的命令(3种方法):1、lsb_release -a(提示命令不存在则运...

在Linux系统中,环境变量是实现全局命令访问的核心机制。无论您身处哪个目录,都能直接执行cd、pwd等命令,这背后正是PATH环境变量的功劳。本文将深入解析环境变量原理与实战配置技巧。一、环境变量核心作用与原理1. 全局访问机制 PATH变量存储命令搜索路径,系统执行命令时按路径顺序查找可执行程序 类比Windo

在Linux系统中挂载新硬盘需要经过以下步骤:1. 识别新硬盘sudo fdisk -l或使用 lsblk 查看新硬盘设备名(如/dev/sdb、/dev/nvme0n1 等)。2. 分区(可选)如果硬盘未分区或需重新分区:sudo fdisk /dev/sdX # 替换 sdX 为您的硬盘设备名输入 n 创建新分区选择分区类型(默认主分区)设置分区大小(默认全盘)输入 w

热门推荐