ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Linux file命令实战:一文掌握文件真实类型识别

Linux file命令实战:一文掌握文件真实类型识别 这次我们来看 Linux 命令系列的第 163 个命令file。先说一个很常见的场景你从网上下载了一个压缩包解压之后发现里面有个文件没有扩展名叫backup你用cat查看输出一堆乱码用vim打开也看不懂。这时候你想知道它到底是什么文件、来自什么程序、是不是可执行文件怎么办不要靠猜用file命令。file的原意是 determine file type作用是识别文件真实类型。它不看文件扩展名而是读取文件的头部特征Magic Number魔法字节再比对系统里的 magic 数据库给出格式化输出。只要 Linux 发行版不是精简到极致file通常都是预装命令来源于 coreutils 或 file 独立项目属于最常用的 Linux 文件管理命令之一。在运维排错、脚本编写、批量文件分类时file的价值主要体现在三点第一识别速度快不需要读完整文件第二结果可靠扩展名可以伪装但文件头不容易伪造第三输出格式稳定方便grep、awk、脚本二次处理。这篇文章会讲清楚file的语法、常用参数、批量识别方法、脚本集成方式以及它在实际排错中的应用。这不是显卡推理、模型部署的教程而是一条纯命令实战教程跟着敲就能跑通。适合刚接触 Linux 的开发者、运维人员也适合正在准备面试、需要系统过一遍常用命令的读者。1. file 命令核心能力速览能力项说明命令全称file - determine file type是否预装绝大多数 Linux 发行版默认自带无需额外安装核心功能通过文件头部特征识别文件真实类型识别原理读取文件开头的 magic number比对 magic 数据库支持类型文本、二进制、可执行文件、压缩包、图片、音频、视频、PDF 等常用选项-b、-i、-f、-L、-z、-k、-s兼容平台Linux、Unix、macOS、Windows Git Bash、WSL批量支持支持可配合通配符、find、循环脚本输出格式文本字符串适合被脚本解析适用场景文件类型识别、批量分类、脚本条件判断、排错分析从表格可以看出file是一个“不需要配置、不需要额外依赖、拿来就能用”的命令。它不像ffprobe那样只针对音视频也不像binwalk那样偏向取证分析file的定位是通用识别覆盖面广输出简单。这里要强调一个容易混淆的点file不校验文件完整性。如果你需要确认文件有没有被完整下载应该用md5sum、sha256sum如果你需要识别文件的真实类型再使用file。两者是不同维度的工作不能相互替代。2. 适用场景与使用边界2.1 适合做什么第一识别无扩展名文件。服务器上经常出现没有扩展名的临时文件、备份文件、导出文件用file一眼就能判断它是文本、压缩包还是可执行程序。第二批量文件分类。运维目录里堆积了大量日志、缓存、临时文件先通过file批量识别类型再按类型归档或清理。第三脚本条件判断。写 Shell 脚本时需要判断用户上传的文件是不是图片、是不是 PDF、是不是可执行文件可以直接用file的输出来做条件分支。第四排错分析。程序报错提示“无法读取文件”时先用file确认文件是否存在、类型是否匹配、是不是被破坏成了未知类型可以迅速缩小排查范围。2.2 不适合什么场景file不适合用来做安全审计。它只能识别文件头无法判断文件是否携带恶意代码。看到一个可执行文件file只能告诉你它是 ELF 可执行文件不能告诉你能不能安全运行。file也不适合替代完整性校验。如果文件头部正常但内容被截断file可能依然显示为正常类型这时候必须用md5sum或sha256sum和原始值比对。另外file不是解压工具。它能识别压缩包类型比如 gzip 压缩数据但不会帮你解压。解压需要配合tar、unzip、7z等工具。2.3 使用边界提醒不要因为file显示某个文件是文本就认为它一定安全。文本文件里可能包含恶意链接、可疑脚本。不要因为file显示某个文件是图片就直接在服务器上执行附带脚本。涉及敏感文件、未知来源文件时先确认授权再决定是否需要进一步分析。对于版权素材、用户私有文件使用file识别类型时注意隐私边界不要将文件内容外传到第三方服务也不要将不含授权的素材用于测试或分发。3. 环境准备与前置条件file命令几乎不需要准备环境但还是需要确认三件事命令是否存在、版本是否够新、magic 数据库是否完整。3.1 检查 file 命令是否存在file --version正常输出类似file-5.41 magic file from /etc/magic:/usr/share/misc/magic.mgc如果提示command not found需要安装。Debian/Ubuntu 系使用 aptsudo apt update sudo apt install file -yCentOS/RHEL/Fedora 系使用 yum 或 dnfsudo yum install file -y # 或 sudo dnf install file -ymacOS 一般自带file。Windows 用户可以在 Git Bash、WSL 或 Cygwin 环境中使用。3.2 检查 magic 数据库file的识别能力依赖 magic 数据库通常在以下路径/etc/magic/usr/share/misc/magic.mgc/usr/share/file/magic.mgc如果这些文件损坏或缺失file的输出会变得不准确大量文件都显示为data。此时需要重装file软件包。3.3 权限注意识别文件类型时至少需要对目标文件有读取权限。如果文件权限是000即使 root 用户也可能受到文件系统安全策略限制更稳妥的方式是先确认当前用户有权读取目标文件。ls -l backup如果没有读取权限先调整权限或使用sudo。sudo file backup4. file 命令基础语法与参数说明4.1 基本语法file [选项] 文件或目录如果参数是目录file默认只显示目录本身的信息不会递归识别目录里的文件。4.2 常用参数速查参数作用示例-b不显示文件名只输出类型file -b test.png-i输出 MIME 类型和编码file -i test.png-f从文件列表读取文件名file -f list.txt-L跟随符号链接识别真实文件file -L link-z识别压缩文件内部的内容file -z app.tar.gz-k不中断继续输出所有匹配规则file -k test.bin-s读取块设备或特殊文件file -s /dev/sda4.3 参数组合示例最常用的组合是-b和-i。file -b test.txt输出ASCII textfile -i test.txt输出text/plain; charsetus-ascii-i的输出更适合脚本解析因为它是标准 MIME 格式方便用字符串匹配判断文件类型。先启动一个测试环境创建几类典型文件再逐一验证mkdir -p /tmp/file-test cd /tmp/file-test echo hello linux file command a.txt cp /bin/ls b_exec echo #!/bin/bash c.sh echo echo test c.sh head -c 100 /dev/urandom d.bin tar czf e.tar.gz a.txt5. 功能测试与效果验证5.1 识别文本文件file a.txt预期输出a.txt: ASCII text使用-i参数file -i a.txt输出a.txt: text/plain; charsetus-ascii判断成功标准输出中包含text字样表示文件被识别为文本类型。如果希望确认文件是否包含 UTF-8 中文可以创建一个中文文本再测试echo 中文内容测试 chinese.txt file -i chinese.txt输出中会出现charsetutf-8说明编码识别正常。5.2 识别可执行文件把/bin/ls复制成无扩展名文件cp /bin/ls b_exec file b_exec预期输出b_exec: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]..., for GNU/Linux 3.2.0, stripped这里的关键信息是ELF 64-bit LSB pie executable说明它是一个 Linux 下的 64 位可执行文件。5.3 识别 Shell 脚本file c.sh预期输出c.sh: Bourne-Again shell script, ASCII text executable这里要注意file识别脚本靠的是文件开头的#!行shebang。如果去掉#!行file会把它识别为普通文本。echo echo test c_no_shebang.sh file c_no_shebang.sh输出c_no_shebang.sh: ASCII text这个细节在排错时非常有用如果脚本执行时报错No such file or directory很可能是因为脚本的 shebang 行指向了解释器路径不存在或者脚本文件是 Windows 换行符而不是因为文件本身被删除。5.4 识别随机二进制数据file d.bin预期输出d.bin: datadata表示文件头没有匹配到任何已知 magic number。这种情况常见于加密文件、自定义格式文件、压缩后再次改名的文件。5.5 识别压缩包file e.tar.gz预期输出e.tar.gz: gzip compressed data, from Unix, original size modulo 2^32 10加-z参数可以看到压缩包内部的内容类型file -z e.tar.gz输出e.tar.gz: POSIX tar archive (GNU) (gzip compressed data, from Unix, original size modulo 2^32 10)这里可以看到两层信息外层是 gzip 压缩内层是 tar 归档。5.6 识别软链接真实类型ln -s a.txt link_to_a file link_to_a默认输出link_to_a: symbolic link to a.txt使用-L跟随链接file -L link_to_a输出link_to_a: ASCII text这说明加-L后file识别的是链接指向的真实文件而不是链接本身。这个参数在处理符号链接目录时很实用。6. 批量识别与脚本集成6.1 使用通配符批量识别file /tmp/file-test/*输出会逐行列出每个文件的类型。适合文件数量不多、直接看结果的场景。如果文件数量很多建议使用-b去掉文件名再配合排序统计file -b /tmp/file-test/* | sort | uniq -c输出类似1 ASCII text 1 ELF 64-bit LSB pie executable 1 gzip compressed data这样可以直接看出目录里有哪些类型的文件每种类型有多少个。6.2 使用 -f 从文件列表读取当文件名包含特殊字符、空格或需要从文本列表批量处理时用-f更稳定find /var/log -type f -name *.log /tmp/log-list.txt file -f /tmp/log-list.txt这样可以避免命令行参数过长的问题也方便把待处理的文件列表交给其他脚本统一维护。6.3 配合 find 遍历目录find找到了所有文件再交给file做类型判断是最常见的组合find /tmp/file-test -type f -exec file {} \;如果想让输出更紧凑可以使用-exec ... find /tmp/file-test -type f -exec file {} 6.4 按类型自动归档写一个简单的 Shell 脚本自动把图片、文本、可执行文件分类到不同目录#!/bin/bash SOURCE_DIR/tmp/mixed TARGET_DIR/tmp/classified if [ ! -d $SOURCE_DIR ]; then echo Source directory does not exist: $SOURCE_DIR exit 1 fi mkdir -p $TARGET_DIR/{text,image,binary,other} for f in $SOURCE_DIR/*; do [ -e $f ] || continue mime$(file -b --mime-type $f) case $mime in text/*) cp $f $TARGET_DIR/text/ ;; image/*) cp $f $TARGET_DIR/image/ ;; application/octet-stream) cp $f $TARGET_DIR/binary/ ;; *) cp $f $TARGET_DIR/other/ ;; esac done echo Classification complete.这里用了file -b --mime-type只输出 MIME 类型比如text/plain、image/png、application/octet-stream脚本通过case做分支非常稳定。测试方式mkdir -p /tmp/mixed cp /bin/ls /tmp/mixed/ cp /etc/passwd /tmp/mixed/ cp /tmp/file-test/a.txt /tmp/mixed/ bash classify.sh执行后查看/tmp/classified目录find /tmp/classified -type f应该能看到文件被正确归档。6.5 在 Shell 条件判断中使用if file -b $1 | grep -q ASCII text; then echo This is a text file. else echo This is not a text file. fi也可以直接匹配 MIMEmime$(file -b --mime-type $1) if [ $mime image/png ]; then echo PNG image detected. fi这种写法在业务系统上传文件校验时很常用可以避免用户把恶意脚本伪装成图片上传。7. 实际排错场景应用file在排错中不是主角但它能帮你快速缩小问题范围。下面是几个常见排错场景。7.1 脚本执行报错 No such file or directory报这个错有时候不是因为文件不存在而是因为脚本的 shebang 行解释器路径不对或者脚本文件是 Windows 换行符。先确认文件是否存在ls -l run.sh再确认文件类型:file run.sh如果输出是run.sh: ASCII text, with CRLF line terminators说明是 Windows 换行符问题。用sed转换成 Unix 格式sed -i s/\r$// run.sh转换后再执行bash run.sh7.2 程序提示 cannot open source input file这类提示通常来自编译器、解释器或构建工具原因是输入文件不存在、路径错误、权限不足或文件类型不匹配。先用file确认目标文件file /path/to/source.c如果输出显示文件类型不是预期类型而是data说明文件可能被损坏或者根本不是 C 源码文件。再检查权限ls -l /path/to/source.c如果权限位是----------需要先调整权限chmod r /path/to/source.c7.3 文件权限或安全属性错误在日志中看到类似could not set file security for file的错误时通常是文件系统不支持某种安全属性或者当前用户没有权限设置 ACL。先确认文件类型和所在文件系统file /path/to/target df -T /path/to/target如果目标文件是特殊文件比如 socket、设备文件而程序把它当普通文件处理也会出现异常。此时file -s可以读取特殊文件类型file -s /dev/null输出/dev/null: character special看到character special说明这是字符设备文件不能作为普通文本文件打开。7.4 检查上传文件是否被篡改用户上传了一个jpg但服务器一直报解析失败。用file看一下真实类型file upload.jpg如果输出是upload.jpg: HTML document, ASCII text说明文件内容其实是网页代码只是扩展名改成了jpg。这种情况在文件上传漏洞测试、恶意文件伪装时很常见file能快速识别出来。8. 常见问题与排查方法问题现象可能原因排查方式解决方案file: command not found系统未安装 file 命令执行file --version用 apt/yum/dnf 安装 file大量文件显示为datamagic 数据库损坏或缺失检查/usr/share/misc/magic.mgc是否存在重装 file 软件包扩展名与识别结果不一致文件被改名或内容与扩展名不匹配用file -i查看 MIME 类型以file结果为准不要信任扩展名中文文件名乱码终端编码与文件系统编码不一致执行locale查看系统编码调整终端字符编码为 UTF-8无法读取文件权限不足执行ls -l查看权限位使用sudo或调整文件权限符号链接显示的是链接信息未加-L参数检查是否使用file -L加-L跟随链接识别真实文件脚本执行报No such file or directoryshebang 路径错误或 CRLF 换行使用file run.sh查看详细信息修正解释器路径或用sed转换换行符file -f读取列表无输出列表文件为空或路径错误查看列表文件内容确认列表文件路径和编码正确输出结果很长匹配到多种 magic 规则使用-b减少输出内容按需使用-b、-i简化输出9. 最佳实践与使用建议9.1 第一次使用先加 -ifile -i输出标准 MIME 类型比默认的长文本描述更适合快速判断。尤其在批量处理时text/plain、image/png、application/pdf这种格式更好匹配。9.2 批量任务加日志和重试如果要把file集成到批量处理流程建议把处理结果写到日志文件方便出问题时回溯。find /data -type f -exec file {} \; /tmp/file-scan.log 21处理完成后检查日志中有没有cannot open这类错误。9.3 脚本判断优先用 --mime-type不要用完整输出来做字符串匹配因为不同版本的file输出格式略有差异但--mime-type输出相对稳定file -b --mime-type somefile输出text/plain9.4 文件目录分开放建议建立清晰的目录结构模型文件、输入素材、输出结果、日志分目录管理。即使只是做文件类型识别测试也建议在独立目录中操作避免在系统关键目录里创建测试文件。9.5 合法使用与隐私合规在识别用户文件、批量扫描服务器目录时注意权限和隐私边界。不要扫描无权限访问的目录不要将用户文件内容输出到公开日志不要对未授权文件做传播或二次分发。如果文件涉及版权素材识别类型后不要绕过授权使用。9.6 配合 find 和权限控制批量扫描时设置-type f排除目录配合-maxdepth控制扫描深度避免扫描整个磁盘导致性能下降find /data -maxdepth 2 -type f -exec file {} \;10. 总结与下一步file命令最大的价值就是一个字稳。它不依赖扩展名不需要额外安装输出格式稳定单文件识别速度极快。对于日常需要频繁判断文件类型的场景file是成本最低的解决方案。如果把它放进脚本组合里你能做的事会多很多——按类型归档、拦截伪装文件、检查上传文件、批量分类日志每一样都能在实际工作中直接落地。先把基础的file、file -b -i、file -f、file -L这几种用法记熟。初次上手时建议先建一个测试目录放几类不同文件逐个识别验证然后再尝试写一个小分类脚本。最容易踩的坑有两个一个是只信扩展名另一个是忽略file输出中data的含义——data不代表文件没有内容而是说它没匹配到已知类型需要进一步用xxd或strings查看。后续可以继续关注find、grep、xxd、stat这些搭配命令。掌握file的判断逻辑后再学 MIME 类型、magic number 相关的知识会更容易理解 Linux 系统是如何分类文件的。下次遇到不认识的文件先file一下比盲猜有效得多。
返回列表