3、Linux系统基础:Linux常用命令、文件系统与权限管理、Shell脚本编程
说实话,很多嵌入式新手一上来就追着芯片手册啃,却忽略了Linux这个基本功。我见过不少同事,代码写得不错,但连个日志文件都查不明白,调试效率低得让人着急。Linux对于嵌入式AI工程师来说,就像手术刀对于外科医生——你得用得顺手才行。
3.1 常用命令:别只会cd和ls
我刚开始带团队时,发现一个有趣的现象:很多人翻来覆去就用那五六个命令。其实Linux命令库很丰富,关键是要知道哪些最实用。
日常高频命令清单(我个人每天至少用一遍的):
| 命令 | 用途 | 我的习惯用法 |
|---|---|---|
find |
查找文件 | find . -name "*.log" | xargs grep "error" |
grep |
文本搜索 | grep -rn "malloc" --include="*.c" |
awk |
文本处理 | awk '{print $1, $NF}' log.txt |
sed |
流编辑 | sed -i 's/old/new/g' file.c |
top/htop |
进程监控 | 看CPU和内存占用,排查死循环 |
举个例子,我在调试一个AI推理程序时,发现内存泄漏。用top一看,RES一直在涨。再用strace -p [PID]跟踪系统调用,很快就定位到是某个驱动没释放DMA缓冲区。你想想看,如果没有这些命令,光靠printf打日志,得查到什么时候?
小技巧:用history | grep 某命令找回你昨天用过的复杂命令。我经常这么干,省得重新敲一遍。
3.2 文件系统与权限管理:别让权限卡住你
嵌入式设备上,文件系统结构跟PC不太一样。比如/sys和/proc这两个虚拟文件系统,里面藏着硬件状态和内核信息。我曾在调试摄像头驱动时,就是通过/sys/class/video4linux下的节点找到了设备参数。
权限这块,嗯,这里要注意。很多嵌入式工程师图省事,直接chmod 777。我曾经接手过一个项目,前任把所有文件都设成777,结果产品上线后被攻击者利用了一个脚本漏洞,整个系统被搞瘫了。从那以后,我对权限管理格外严格。
避坑指南:我曾经因为/tmp目录权限设置不当,导致两个进程互相覆盖了对方的临时文件,查了整整两天才找到原因。记住:/tmp的sticky bit一定要保留(chmod +t /tmp)。
权限管理的核心就三句话:
- 用户:谁在用?root还是普通用户?
- 组:属于哪个项目组?
- 权限:读、写、执行,分别给谁?
用ls -l看文件权限时,那串-rwxr-xr--其实很好记:前三组是所有者、所属组、其他人。每组三个字符,对应r(读)、w(写)、x(执行)。
实战场景:你写了一个AI推理脚本,想让同组的同事能运行但不能修改。那就设成chmod 755 script.sh。如果想让所有人都能执行但只有你能改,那就是chmod 744。
3.3 Shell脚本编程:把重复劳动自动化
说白了,Shell脚本就是把你每天敲的命令串起来。我刚开始做嵌入式时,每次编译完都要手动拷贝固件到开发板、重启、看日志。后来写了个脚本,一键搞定。你想想看,省下来的时间能多喝几杯咖啡。
一个典型的嵌入式AI工作流脚本长这样:
#!/bin/bash
# 编译AI模型部署程序
echo "开始编译..."
make clean && make -j4
if [ $? -ne 0 ]; then
echo "编译失败!请检查代码"
exit 1
fi
echo "编译成功,开始部署..."
scp output/binary root@192.168.1.100:/opt/app/
ssh root@192.168.1.100 "systemctl restart ai-service"
echo "查看日志..."
ssh root@192.168.1.100 "journalctl -u ai-service -n 50 --no-pager"
这里有几个关键点:
$?:上一条命令的返回值,0表示成功。我习惯在每个关键步骤后检查它。-ne:不等于。Shell里的比较运算符跟C语言不一样,别搞混了。scp和ssh:远程操作三板斧。我建议配置SSH密钥登录,省得每次输密码。
我的习惯:写脚本时,变量名用大写,函数名用小写。比如BINARY_PATH="./output/",deploy_app()。这样一眼就能分清变量和函数。
再深入一点,讲讲函数和参数传递。我写脚本时,会把重复逻辑封装成函数:
check_status() {
if [ $1 -ne 0 ]; then
echo "错误:$2 失败"
exit 1
fi
}
# 使用
make -j4
check_status $? "编译"
这样主逻辑就清晰多了。你想想看,如果每个步骤都写一遍if判断,脚本会变得又臭又长。
注意:我曾经在脚本里用rm -rf ${DIR}/,结果DIR变量没赋值,变成了rm -rf /。嗯,那场面...从那以后,我每次用rm都先echo一下路径,确认无误再执行。
最后,推荐几个调试技巧:
- 用
bash -x script.sh执行,会打印每条命令的执行过程。 - 在脚本开头加
set -e,遇到错误自动退出,避免连锁反应。 - 用
trap捕获信号,确保脚本被中断时能清理临时文件。
Linux基础这块,说白了就是多用、多练、多踩坑。我到现在还会时不时翻翻man手册,每次都能发现新东西。别指望一次学完,慢慢积累就好。