第三章:Linux基础与Shell编程

说实话,很多做自动驾驶的朋友,代码写得飞起,但一进Linux终端就发怵。我当年刚入行时也是这样,总觉得有IDE就够了。直到有一次,我在调试一个传感器数据流的问题,IDE死活连不上,最后靠着一行grepawk,五分钟定位了问题。嗯,从那以后,我再也不敢小看Shell了。

这一章,我们就来聊聊自动驾驶软件栈里,那些你绕不开的Linux基础。说白了,就是让你能在终端里「活下来」,并且活得挺滋润。

3.1 Linux文件系统:你得知道东西放哪了

Linux的文件系统,和Windows不一样。它没有C盘D盘,而是一棵树。根目录是/,所有东西都挂在这棵树上。

我建议你重点记住这几个目录:

  • /bin/usr/bin:放的是常用命令,比如lscp。你想想看,没有这些命令,你连文件都看不到。
  • /etc:系统配置文件。我在项目中遇到过,传感器驱动死活装不上,最后发现是/etc/udev/rules.d里的权限规则没写对。
  • /var/log:日志文件。调试时第一站就是这里。自动驾驶系统跑着跑着出问题了,先看/var/log/syslog
  • /proc:虚拟文件系统,存的是内核和进程信息。比如/proc/cpuinfo能看CPU型号。
  • /dev:设备文件。你的激光雷达、摄像头,挂载后都会在这里出现。
小技巧: 我个人习惯用 tree -L 2 / 快速看目录结构。别死记硬背,多用几次就熟了。

3.2 常用命令:grep、awk、sed 三剑客

这三个命令,是Linux文本处理的「倚天剑屠龙刀」。你写自动驾驶代码,天天要和日志、配置文件打交道,不会它们,效率至少低一半。

3.2.1 grep:大海捞针

grep 就是用来在文件里找字符串的。比如你怀疑某个传感器报错了:

grep -rn "ERROR" /var/log/autonomous_drive.log

-r 是递归,-n 是显示行号。我曾经在调试一个路径规划模块时,日志文件有几十万行,全靠grep一把梭。

更高级的用法,是用正则表达式。比如你想找所有以lidar开头的行:

grep "^lidar" sensor_config.yaml

3.2.2 awk:列处理神器

awk 默认把一行按空格或Tab切分成多列。比如你有一个CSV文件,想提取第二列:

awk '{print $2}' data.csv

我在项目中遇到过,需要从传感器时间戳日志里,提取出所有超过100毫秒的延迟记录:

awk '$3 > 100 {print $1, $2, $3}' latency.log

这里$3是第三列,如果大于100,就打印前三列。你看,一行命令搞定。

3.2.3 sed:流式编辑器

sed 用来做文本替换。比如你想把配置文件里所有的debug=false改成debug=true

sed -i 's/debug=false/debug=true/g' config.yaml

-i 是直接修改文件,s 是替换命令,g 是全局替换。注意,-i 很危险,我建议你先不加-i跑一遍,看看输出对不对。

警告: 我曾经有一次手滑,用 sed -i 把整个配置文件清空了。嗯,从那以后,我每次用 sed -i 之前,都会先 cp 备份一下。

3.3 Shell脚本编写:把重复劳动自动化

你每天要启动传感器、录制数据、编译代码……这些事,写个脚本一键搞定,不香吗?

一个典型的自动驾驶数据采集脚本,大概长这样:

#!/bin/bash
# 数据采集脚本

LOG_DIR="/data/logs/$(date +%Y%m%d_%H%M%S)"
mkdir -p $LOG_DIR

echo "启动激光雷达..."
roslaunch lidar_driver lidar.launch &
LIDAR_PID=$!

echo "启动摄像头..."
roslaunch camera_driver camera.launch &
CAM_PID=$!

echo "开始录制..."
rosbag record -O $LOG_DIR/recording.bag /lidar_points /camera_image

# 录制结束后,清理进程
kill $LIDAR_PID $CAM_PID
echo "采集完成,数据保存在 $LOG_DIR"

这里有几个要点:

  • #!/bin/bash 是脚本的「身份证」,告诉系统用哪个解释器。
  • $(date +%Y%m%d_%H%M%S) 是命令替换,生成时间戳文件夹。
  • & 让进程后台运行,$! 获取它的PID,方便后面杀掉。

我个人习惯,脚本里一定要加set -e。这样一旦某条命令失败,脚本就立即退出,不会继续执行造成更大的混乱。

3.4 进程管理与调试工具

自动驾驶系统跑起来,进程少说几十个。怎么管?

3.4.1 ps 和 top:看看谁在跑

ps aux 列出所有进程。你想找某个进程,比如rosmaster

ps aux | grep rosmaster

top 是动态的,实时显示CPU和内存占用。我调试性能问题时,经常开着top,看看哪个进程在偷吃资源。

3.4.2 kill:该停就停

进程卡死了?kill -9 PID 是终极手段。但注意,-9 是强制杀死,进程没有机会做清理工作。我建议先用kill -15,给进程一个优雅退出的机会。

3.4.3 strace 和 gdb:调试利器

strace 跟踪系统调用。比如你的程序读文件很慢,可以用strace -p PID看看它在干嘛。

gdb 是调试器。程序崩溃了,生成core dump文件,然后用gdb ./program core,就能看到崩溃时的调用栈。我在项目中遇到过,一个内存越界问题,查了两天没头绪,最后靠gdb定位到了。

核心总结: Linux基础不是让你背命令,而是让你在遇到问题时,知道用什么工具去解决。grep找文本,awk处理列,sed改文件,ps/kill管进程,strace/gdb查bug。这些工具,你用得越多,就越离不开它们。

好了,这一章的内容就到这里。记住,Shell脚本是你自动驾驶开发路上的「瑞士军刀」,别嫌它丑,用起来真香。


专注资料整理