Linux的常用指令--file
作为一个嵌入式 Linux 程序员,尤其是做交叉编译开发时,你一定遇到过这种 “崩溃时刻”:辛辛苦苦在 PC 上交叉编译好程序,烧到 RV1126b 开发板上一跑,直接提示 cannot execute binary file: Exec format error—— 折腾半天,才发现是把 64 位程序编译给了 32 位板,或者架构完全不对。这时候,你需要一个交叉编译里的 “程序安检员”—— 它就是 file。
在我看来,file 就像交叉编译流程里的 “第一道关卡”,能一眼看穿程序的 “真实身份”:是给 32 位还是 64 位系统编译的?是 ARM、x86 还是其他架构?字节序是大端还是小端?不用等到烧到板上,用 file 查一下就能提前避坑,节省大把调试时间。
下面开始看例子,就结合我们熟悉的 RV1126b(32 位 ARM Cortex-A7)开发场景。
假设你在 PC 上编译了三个程序:test_x86_64(本机 64 位程序)、test_arm32(交叉编译的 32 位 ARM 程序)、test_arm64(不小心编错的 64 位 ARM 程序)。这时候分别用 file 查一下:
先查本机编译的 64 位程序:
file test_x86_64
输出会告诉你:这是给 x86-64 架构、64 位 Linux 系统编译的,放到 ARM 板上肯定跑不起来。
再查正确的 32 位 ARM 交叉编译程序:
file test_arm32
输出会显示:这是 ARM 32-bit、小端序、Linux ELF 格式的程序 —— 这才是 RV1126b 能跑的 “正确身份”。
最后查不小心编错的 64 位 ARM 程序:
file test_arm64
输出会提示:这是 AArch64(ARM 64 位)架构的 —— 放到 32 位的 RV1126b 上,自然会报格式错误。
看到这里,相信大家已经感受到 file 在交叉编译里的实用了。接下来就看看 file 针对交叉编译的 “核心输出信息” 和 “核心用法”:
先搞懂:file 输出里的交叉编译关键信息
用 file 查可执行文件时,输出里这几个部分对交叉编译最重要:
- 架构类型:比如 x86-64、ARM、AArch64、MIPS 等,必须和目标开发板的 CPU 架构一致。
- 位数:32-bit 或 64-bit,RV1126b 是 32 位,就不能用 64 位程序。
- 字节序:little-endian(小端)或 big-endian(大端),嵌入式里很多 ARM 板是小端,字节序错了也跑不起来。
- 文件格式:ELF(Linux 标准可执行格式),确认是 Linux 程序而不是 Windows 的 PE 格式。
比如一个正确的 RV1126b 程序,file 输出大概长这样:
test_arm32: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-armhf.so.3, for GNU/Linux 3.2.0, not stripped
这里的 32-bit LSB ARM 就是关键 ——32 位、小端、ARM 架构,完美匹配 RV1126b。
再讲 file:交叉编译场景下的核心用法
查单个程序的架构:最基础的用法,编译完先查一下再烧板
file test_program
批量查编译产物:如果编译出多个 .elf 或可执行文件,批量检查避免漏网之鱼
file *.elf
查软链接指向的真实程序:如果用软链接管理不同版本的程序,加 -L 参数查真实文件的架构
file -L link_to_latest_program
简洁输出关键信息:如果要写脚本自动检查,加 -b 参数只输出核心内容,方便解析
file -b test_arm32
小技巧:交叉编译后的 “必查流程”
为了避免架构不匹配的坑,建议养成这个习惯: 交叉编译完成后,第一时间用 file 查程序架构,确认是目标板的 32/64 位、正确的 CPU 架构。
如果不确定,结合 readelf 一起用,更详细地看机器信息:
readelf -h test_program | grep Machine
比如 RV1126b 的输出会是 Machine: ARM,64 位 ARM 板会是 Machine: AArch64。
写个小脚本批量检查:如果项目编译产物多,写个简单的 shell 脚本,用 file 和 grep 批量过滤出架构不对的程序,比如:
# 检查当前目录下所有可执行文件是否是ARM 32位
for file in *; do
if [ -x "Misplaced &Misplaced &file" ]; then
if ! file "$file" | grep -q "ARM 32-bit"; then
echo "警告:$file 不是ARM 32位程序!"
fi
fi
done
总结
file 命令在交叉编译里的核心价值,就是当你的 “程序预检员”—— 不用烧到板上,就能提前发现架构、位数、字节序不匹配的问题,避免浪费时间在 “为什么程序跑不起来” 的低级错误上。记住:交叉编译完,先 file 查一下,这是嵌入式开发的好习惯~
file 的大致用法就讲到这里,大家有什么用 file 查交叉编译程序的有趣经历,或者其他交叉编译避坑小技巧,欢迎在评论区交流~