拿到IMX6ULL开发板的第一天,插上电源,用串口线连上电脑,屏幕上是黑底白字的登录提示符。很多人的嵌入式Linux之路就是这么开始的:没有桌面、没有鼠标,面对的是一个只有命令行的小世界。这套系列文章就是陪着那些在串口终端面前发懵的朋友,一步一步把嵌入式Linux的基础打牢。这一篇讲的是整个系列的地基——Linux文件目录和目录相关命令。别小看它们,后续的交叉编译、驱动加载、应用部署、系统移植,没有哪一步能绕开这套基本功。
我见过不少学习者,上来就急着搜“怎么写驱动程序”“怎么点亮LED”,结果一遇到路径不对、找不到文件、误删了系统目录这类问题就卡住很久。原因很简单:你对文件和目录这套操作没有形成直觉。本文不打算把命令表罗列一遍就完事,而是结合IMX6ULL开发板的实际使用场景,把每个命令为什么这样用、在板子上会和虚拟机里有什么差异,一次说清楚。
1. 为什么嵌入式Linux的第一课,总落在文件和目录上
1.1 从Windows的“盘符思维”切换到Linux的“树状思维”
我们大多数人第一次接触电脑都是Windows。Windows的存储心智模型是“盘符”:C盘装系统,D盘放资料,U盘插上去就是E盘。这种模型很简单,因为每个存储设备都有自己独立的“根”。
Linux完全不是这个思路。它只有一个根:/。不论是一张SD卡、一块eMMC、一个U盘,还是一个网络共享目录,都要先“挂载”到这个根目录下的某个位置,然后你通过那个位置去访问它。这根Windows里“把U盘插进USB口”是两个完全不同的逻辑——Linux不关心数据在哪个物理设备上,只关心你在目录树里的什么位置。
IMX6ULL开发板更是如此。它的系统可能存放在eMMC里,也可能在SD卡里,或者通过TFTP从电脑上加载。但不管启动介质是什么,一旦系统跑起来,你看到的永远是那一棵从/开始的目录树。如果你还用“找盘符”的思维去操作,很容易出现“文件明明在卡里,为什么我在根目录下找不到”的困惑。
1.2 IMX6ULL开发板上的Linux,和虚拟机里的Ubuntu不是一回事
很多人在学嵌入式之前,先在VMware里装了个Ubuntu练手。那个环境当然很好,但别把经验完全照搬到开发板上。有几个差异特别明显:
- 命令集是裁剪过的。开发板上的很多基础命令由BusyBox提供,它把几十个命令打包成一个可执行文件,参数支持范围比台式机上的完整版GNU工具链小得多。
ls、find这些命令的基本用法没问题,但一些高级参数可能直接不支持。 - 默认就是root用户。开发板出厂系统为了方便调试,串口登录后直接就是root身份,没有权限保护。这意味着
rm -rf这种命令一旦敲错,系统不会拦你,它是真的会直接删掉。 - 没有额外的保护层。开发板上的文件系统是精简的,没有图形界面占空间,但同样的,也没有回收站、没有恢复分区。删掉的库文件、误覆盖的脚本,很多时候只能重新烧写整个系统。
理解了这些差异,你就会明白:在开发板上敲命令,比在虚拟机里更需要养成清醒、谨慎的习惯。这也是为什么我强烈建议新手从文件和目录操作开始练,先在一个低风险的环境里建立肌肉记忆。
2. 登录IMX6ULL后的第一步:先搞清楚自己站在哪
2.1 pwd:每到一个新环境,先问路
第一次通过串口登录IMX6ULL,登录成功后你会看到类似这样的提示符:
#就一个井号,什么都不显示。它其实在告诉你两件事:当前用户是root(root的提示符默认是#,普通用户是$),然后就没有然后了。有些固件会配置一下提示符,显示当前路径,比如/root #,但很多出厂固件为了省空间,提示符就是光秃秃的。
所以第一件事,养成输入pwd(print working directory)的习惯:
# pwd /rootpwd就是回答“我在哪”的命令。它输出当前所在的绝对路径。在开发板上调试时,我每次登录后的习惯动作就是先pwd,尤其是一段时间没操作、串口已经刷了几屏日志之后,更需要确认自己是不是还在原来的目录。
这里有个细节:很多开发板的默认登录目录是/root,而不是普通Linux里的/home/用户名。因为板子上没有给你创建普通用户,直接就是root家目录。如果你发现pwd输出的是/而不是/root,也别奇怪,说明系统没有做家目录配置,直接停在根目录了。
2.2 cd:路径切换的几种姿势,以及嵌入式下的限制
cd(change directory)是切换目录的命令。基础用法人人都会:
# cd /etc # pwd /etc但有几种切换方式值得单独拿出来说:
cd ..:回到上一级目录。这个在嵌入式调试时太常用了。比如你在/home/root/work下编译文件,想回到/home/root看看别的源码,直接cd ..。cd ~:回到当前用户的家目录。root用户就是/root。cd -:回到上一次所在的目录。这个命令特别好用。你在/etc下改完配置,cd -一下就能回到刚才/home/root/work的编译现场,不用重新敲长路径。- 绝对路径vs相对路径:
cd /etc用的是绝对路径,不管你在哪都能去;cd work用的是相对路径,它是基于当前位置的。新手最容易踩的坑就是把相对路径当成绝对路径用,结果cd work提示“no such file or directory”,其实不是目录不存在,是你当前不在它所在的父目录里。
嵌入式环境下SPI要注意一个情况:完整的Bash是支持Tab键自动补全路径的,但开发板上因为是BusyBox的shell(通常是ash),部分固件默认没有启用路径补全,或者补全能力很弱。你按了一下Tab没反应,别以为是键盘坏了,这是环境本身的限制。解决办法也简单:路径尽量用绝对路径,或者自己把路径敲完整,别扭的地方忍一忍,后面熟练了就不觉得是什么大问题了。
2.3 ls:把当前目录的内容看个透彻
ls可能是你用得最多的命令,没有之一。最基本的就是直接输入ls,把当前目录下的文件和子目录名字列出来:
# ls app driver README.md但真正调试时要的是细节,所以ls -l几乎是必用的:
# ls -l drwxr-xr-x 2 root root 4096 Jan 1 00:00 app -rw-r--r-- 1 root root 1024 Jan 1 00:01 README.md这条命令输出的一大串信息怎么读,值得花点时间:
- 第一个字符表示文件类型:
d是目录,-是普通文件,l是符号链接(软链接),b是块设备(比如SD卡、eMMC),c是字符设备(比如串口、触摸屏)。 - 后面9个字符是权限位,分成三组:属主权限、属组权限、其他人权限。
rwx分别是读、写、执行,-表示没有对应权限。 - 再往后是硬链接数、属主、属组、文件大小、最后修改时间、文件名。
开发板上看设备节点时,这个命令尤其有用。比如/dev目录下有很多设备文件,ls -l /dev/一看就能分清哪个是块设备(b开头)、哪个是字符设备(c开头)。
ls还有几个高频参数组合:
# ls -la # ls -lh # ls -R-a是显示隐藏文件(文件名以.开头的),嵌入式文件系统里很多配置文件是隐藏的,比如/etc下的某些运行态文件。-h是human-readable,把文件大小显示成4.0K、1.2M这样好读的单位,调试时判断文件是不是完整复制过来很有用。-R是递归列出子目录,在BusyBox里能替代缺失的tree命令。
我在板子上常用的一套组合是ls -lh,信息够用、输出不至于太长。串口终端刷屏很慢,如果直接ls -lR整个根目录,那个输出量会让你等到怀疑人生。
3. 开发板上的目录操作命令:组合拳怎么打
3.1 mkdir和rmdir:创建与删除目录
在开发板上工作,第一步通常是建立自己的工作目录。比如我想把学习代码放在/home/root/work下,一条命令就能建好:
# mkdir -p /home/root/work/01_led-p参数的意义是:如果/home/root不存在,那就一并创建出来。不加-p的话,只要父目录缺一级,命令就报错。这个参数在写脚本时尤其重要,脚本里经常要保证某个目录存在,直接mkdir -p最省心。
删除目录对应的是rmdir,但它有个让人抓狂的限制:只能删除空目录。在实际开发中,目录里几乎总有文件,所以rmdir的使用频率非常低。更常用的是rm -r,这个后面单独说。
这里分享一个我自己在板子上的习惯:所有实验代码都建在/home/root/work下,按编号建子目录,比如01_led、02_key、03_uart。这么做的好处是,当目录结构清晰时,后续编译、部署、备份都会非常顺手。你如果一开始就随手建在根目录或者/tmp下,过两周再回头看,自己都找不到东西在哪。
3.2 从cp到mv再到rm:文件操作三件套
cp用来复制文件。单文件复制很简单:
# cp hello.c /home/root/work/01_led/复制整个目录就必须加-r:
# cp -r /home/root/project /home/root/work/如果你希望连同文件属性、时间戳一起保留(比如复制一个带可执行权限的脚本),用cp -a更合适。-a等同于-dpR,保留一切属性。在板子上拷贝可执行程序时,如果拷完发现没有执行权限,多半是没用-a或者-p把权限位丢了。
mv兼顾移动和重命名两个功能:
# mv old_name.c new_name.c # 重命名 # mv app /home/root/work/ # 移动到别的目录嵌入式板子上尤其要注意:mv在同一文件系统内是瞬时的,但在不同文件系统之间(比如从/tmp到SD卡挂载点/mnt/sd)实际上是“先复制再删除”,大文件会明显卡顿。别以为它卡死了,给它点时间。
rm是最需要敬畏的命令。单文件删除:
# rm test.txt递归删除目录:
# rm -r old_dir/而那条著名的组合rm -rf,在开发板上真的会出人命。-f是强制,不提示、不确认,直接删。如果你在root用户下敲了rm -rf /usr/lib,那系统就半残了。更夸张的,有人敲过rm -rf /,把整个根文件系统删了,开发板当场变砖,只能重新烧写。
我个人的防御性习惯是:凡是删除操作,先ls看清楚目标是什么,再决定用rm还是rm -r;非紧急情况不用-f;删除目录前,先看一眼路径是不是用了相对路径,避免在错误的目录下删错东西。没有回收站的环境里,谨慎就是最大的效率。
3.3 find和其他查询手段:快速定位文件
开发板上的文件系统再精简,也有几千个文件。想找某个文件在哪个目录下,靠cd加ls一个个翻是不现实的。
用find按名字查找:
# find / -name "libc.so*" 2>/dev/null这条命令的意思是:从根目录开始,找名字匹配libc.so*的文件,错误信息丢弃。2>/dev/null是把权限不足产生的报错扔到黑洞里,不然输出里大部分都是“Permission denied”,真正有用的结果反而被淹没了。在嵌入式环境下,这个处理几乎是必须的,因为板子上很多系统目录对root是开放的,但部分特殊文件系统路径还是会刷一堆权限提示。
按文件类型查找也有用,比如只找目录:
# find /etc -type d我只讲这两个最基本的用法。更深度的-exec、-mtime这类参数,在开发板BusyBox上的支持程度参差不齐,不建议新手在板子上深究。
另外,开发板的固件一般没有tree命令。想看目录树结构,就用ls -R代替。输出格式虽然没那么漂亮,但足够梳理结构了。
4. IMX6ULL根文件系统的目录结构:别用Windows的脑子理解/tmp
4.1 标准目录布局:每个目录是干嘛的
Linux根目录下的标准布局是有讲究的,不是随意堆的。我建议在开发板上挨个ls /看一眼,再对照下面的说明,把每个目录的职责记个大概:
| 目录 | 作用 | 嵌入式环境下的注意事项 |
|---|---|---|
/bin | 基本命令 | 通常包含BusyBox,是整个系统最基础的命令集 |
/sbin | 系统管理命令 | 存放ifconfig、mount、reboot这类要求root权限的管理命令 |
/etc | 系统配置文件 | 嵌入式下最核心的目录,基本每个功能都在这里有配置 |
/lib | 库文件 | 存放动态链接库,删错会导致大部分命令无法运行 |
/home | 用户家目录 | 板子上一般只有一个root用户,/home下内容不多 |
/root | root用户的家目录 | 我们的实验代码通常放在这里 |
/usr | 用户程序和数据 | 嵌入式系统可能把它精简掉了,也可能只放少量工具 |
/var | 运行时的可变数据 | 日志、临时锁文件等,重启后内容经常被清掉 |
/tmp | 临时文件 | 重启清空,可以放心折腾 |
/dev | 设备节点 | 字符设备和块设备的入口,由devtmpfs自动管理 |
/proc | 内核虚拟文件系统 | 运行时生成,反映内核和进程状态 |
/sys | 内核设备模型 | 以文件形式暴露设备和驱动的属性 |
/mnt | 挂载点 | 手动挂载SD卡、U盘的常用位置 |
要特别留意/dev、/proc、/sys这三个目录。它们不是真正的磁盘文件夹,而是内核暴露出来的虚拟文件系统。你在/proc/cpuinfo里看到的是CPU信息,在/sys/class/leds下能看到板载LED的驱动节点——这些都是未来写驱动、调应用时天天要打交道的地方。
4.2 嵌入式环境特有的那几个“虚”目录
IMX6ULL板子启动后,你发现/proc和/sys里不是空的,里面有很多文件和目录。这些文件不是你从网上下载放进去的,而是内核实时生成的虚拟文件。它们的作用是让你通过读写文件的方式,去查看内核状态、控制硬件。比如:
# cat /proc/cpuinfo # ls /sys/class/leds/cat /proc/cpuinfo能看到CPU型号、BogoMIPS这些信息;/sys/class/leds/下面一般有heartbeat或LED相关的目录,往特定文件里写东西就能点亮或熄灭板载LED。这就是Linux“一切皆文件”思想的典型体现——连硬件控制都是通过文件读写完成的。
如果哪天你发现/proc或/sys目录是空的,不用急着怀疑系统坏了,多半是因为启动脚本里没有执行mount -t proc proc /proc和mount -t sysfs sysfs /sys。手动补挂一下就好:
# mount -t proc proc /proc # mount -t sysfs sysfs /sys4.3 给新手的三条目录安全红线
在开发板上摸索目录时,有几条我亲身撞过、也看别人撞过的红线,提前说清楚能省很多麻烦:
- 不要随意删除
/lib下的文件。动态链接库之间互相依赖,删掉一个看似没用的小库,可能连ls都运行不了。想验证?我试过,恢复的唯一办法就是重刷文件系统。 - 不要改动
/etc下你不认识的配置文件。尤其inittab、fstab、init.d/rcS这些,它们是系统启动的骨架。改错一个字节,板子可能启动到一半就卡死。 /tmp目录随便用,但别用来放重要文件。它通常是tmpfs(内存文件系统)或纯粹的临时目录,断电重启后内容全部消失。我见过有人把编译产物放到/tmp,断一次电后源码还在、编译好的文件没了,白白重新编译一遍。
5. 在IMX6ULL上实操时最容易踩的坑
5.1 串口终端没有Tab补全、没有鼠标、没有中文
很多新手把虚拟机里的Linux操作习惯带到开发板上,第一个不适应的就是串口终端太难用了。没有鼠标复制粘贴、按Tab不一定能补全、中文文件名直接显示乱码,甚至方向键随便按还会输出乱码字符。
既然是这样的环境,就得用适合它的操作方式。我的做法是:把板子上要用的长命令在PC的记事本或编辑软件里提前准备好,然后通过复制粘贴整个命令到终端。Windows下很多串口工具(如MobaXterm、SecureCRT)都支持粘贴多行命令,比一个字符一个字符敲效率高得多,也避免了敲错的概率。
如果实在要手敲,尽量养成分段小命令的习惯。比如创建目录树,不用一次性敲完一个超长的mkdir,可以分层建,顺便确认每一层路径对不对。
5.2 BusyBox的命令参数是精简版:用之前先自查
开发板上的命令大多来自BusyBox,这玩意的参数和GNU完整版比,是“有一个共同子集”的关系。ls -l没问题,ls --color=auto可能就不认识;rm -rf没问题,rm -I这种交互确认参数可能就没有。在板子上执行不认识的参数,别硬试,先看一眼帮助:
# ls --helpBusyBox的--help输出非常简洁,但足够告诉你当前支持哪些参数了。我的建议是:在虚拟机里先把命令和参数练熟,再到板子上执行。板子上的环境毕竟简单,经不起你反复折腾。
5.3 root身份下,没有“后悔药”
开发板默认root登录,这在方便的同时也意味着所有操作都没有“二次确认”。虚拟机里的Ubuntu普通用户删错了可能只是权限不足,板子上root是畅通无阻地删除一切。
我现在给自己定的规矩是:
- 删除操作之前,先
ls把目标列出来,亲眼确认再删; - 能不用
-f就不用,让系统多问一句不是坏事; - 路径中含有空格或特殊字符的文件,用引号包起来操作,比如
rm "my file.txt"; - 不在确认是否完全理解用途的情况下,不删除只读系统目录里的任何文件。
有人觉得这样太保守,但说真的,开发板重刷一次系统虽然不难,但来回折腾的工时,远不如每条命令前多花几秒钟确认来的划算。
6. 实操训练:在IMX6ULL上搭一个自己的工作区
说到底,命令学的最终目的是用得顺。这里给一套我在板子上过基础命令的开胃训练题,可以原封不动跟着操作一遍,顺便验证自己上面的内容是不是真的理解了。
第一步:建立工作区
# mkdir -p /home/root/work/01_learn # cd /home/root/work/01_learn # pwd预期输出是/home/root/work/01_learn。如果pwd输出不是这个,说明你的cd没有生效,或者当前环境有问题,停下来检查。
第二步:创建几个测试文件
# echo "hello imx6ull" > test1.txt # cp test1.txt test2.txt # mkdir sub_dir # mv test2.txt sub_dir/ # ls -l此时你应该能看到test1.txt和sub_dir目录,test2.txt已经移进子目录里了。
第三步:使用通配符批量操作
# ls *.txt # cp *.txt sub_dir/ # rm test1.txt # ls sub_dir/通配符*在嵌入式shell里是支持的,如果ls *.txt能列出文件,说明当前目录有匹配的文件。这个操作在以后批量部署文件时很有用。
第四步:使用find定位
# find / -name "test2.txt" 2>/dev/null如果前面步骤都正常,这台板子上test2.txt应该只在/home/root/work/01_learn/sub_dir/下面。find能帮你找到它的完整路径,这就是以后面对几千个文件时最实用的招式。
这套操作我建议在IMX6ULL上连做三遍,直到不需要看笔记就能流畅完成。目录命令属于那种“熟能生巧”的功夫,看十遍教程不如亲手敲一遍。下一篇系列会接着讲文件内容查看和编辑,把cat、more、vi这些在开发板上最常用的看文件、改文件的玩法捋一遍。