在 Windows 上,文件类型基本靠扩展名:.docx 是 Word 文档,.jpg 是图片,.exe 是程序。你把一个 .jpg 改成 .txt,它立刻变成"打不开的东西"——扩展名改错了,整个文件就"废"了。
到了 Linux,你会发现规则变了。一个没有扩展名的文件,照样能运行、能被正确识别;一个写着 .jpg 的文件,file 命令一眼就能看穿它其实是个脚本。
反直觉判断:在 Linux 里,扩展名是给"人"看的约定,文件类型是"内容"决定的。这篇讲清 Linux 是怎么"不看名字认文件"的。
Windows 为什么离不开扩展名
Windows 资源管理器靠扩展名决定"双击用什么打开",系统也靠扩展名判断"这是什么"。图标、关联程序、双击行为,全绑在扩展名上。
这个设计有个副产品:攻击者可以把恶意程序伪装成 .jpg、.txt 来骗人双击——反正系统只看名字。这也是 Windows 病毒传播的重要路径之一。
Linux 的三层识别机制
第一层:执行不靠扩展名,靠权限位
Windows 靠 .exe 判断"能不能执行";Linux 靠文件权限里的 x 位:
echo'#!/bin/bash' > helloecho'echo hello' >> hellochmod +x hello./hello# hello
观察点:文件没有任何扩展名,一样能执行。决定它能不能跑的是 chmod +x,不是名字。
第二层:file 命令看"内容"——魔数
Linux 的 file 命令不看名字,直接读文件头部的特征字节(magic bytes):
file hello# hello: Bourne-Again shell script, ASCII text executablefile /bin/ls# /bin/ls: ELF 64-bit LSB executable, x86-64head -c 16 /bin/ls | xxd# 00000000: 7f45 4c46 ... ← ELF 文件头的魔数
观察点:ELF 可执行文件的开头是固定的 \x7fELF,JPEG 图片开头是 \xff\xd8\xff,PNG 是 \x89PNG——这些魔数写在文件内容里,改名字根本骗不了它。
第三层:脚本靠 shebang 决定解释器
脚本文件第一行 #! 开头的"shebang"直接指定解释器,比扩展名可靠得多:
#!/usr/bin/python3#!/bin/bash
观察点:文件名随便叫 run、tool,甚至没有名字,内核都按第一行指定的解释器运行。
这对你意味着什么(工程价值)
- 改扩展名骗不了系统:下载一个可疑文件,
file 一看便知真身是图片还是脚本。 - 危险的不是扩展名,是执行权限:一个伪装成 .jpg 的脚本,只要没有 x 位,就不会被执行——权限位是最后一道闸。
- 写脚本不用纠结命名:
my-script、backup 都能跑,不用强行加 .sh。
# 验货习惯:下载的文件先看真身file suspicious.jpg# suspicious.jpg: POSIX shell script, ASCII text executable
边界:Linux 也不是完全"不看名字"
把话说满容易翻车:
- 桌面环境(GNOME/KDE)也有"默认程序关联",但它基于 MIME 类型(内容嗅探),不是扩展名。
- 编辑器用扩展名做语法高亮提示(vim 看到 .py 高亮 Python),但这是"提示",不是"识别"。
- 有些工具(压缩包、安装包)会用扩展名做快捷判断,但核心识别仍以内容为准。
最后
在 Linux 里,文件类型由内容决定,扩展名只是人与工具之间的约定。
所以记住三件事:识别文件用 file,决定执行用权限位,脚本解释器看 shebang——你就不会在 Linux 里被"名字"骗到。
你用过 file 命令"验证"下载的文件吗?有没有遇到扩展名和真实类型对不上的情况?评论区聊聊。