面试翻车现场

面试过一个候选人,简历上写着"熟悉ROS2开发"。我问他:"你每次打开终端都要source /opt/ros/humble/setup.bash,你知道这个命令做了什么吗?"

他说:"设置环境变量。"

我问:"具体设置了哪些变量?为什么要设置这些变量?"

他说:"就是……让ROS2能用?"

这就是典型的"知其然不知其所以然"。环境变量和路径是Linux开发的基础,特别是ROS2开发,几乎每天都在和环境变量打交道。今天咱们把这些概念彻底搞明白。

环境变量是什么

环境变量就是系统里的"全局配置"。每个进程启动时都会继承一份环境变量,程序通过这些变量获取配置信息。

查看当前所有环境变量:

env              # 查看所有环境变量
echo $PATH       # 查看PATH变量的值
echo $HOME       # 查看用户主目录

常见的环境变量:

  • PATH:可执行文件的搜索路径
  • HOME:用户主目录
  • USER:当前用户名
  • PWD:当前工作目录
  • LD_LIBRARY_PATH:动态库的搜索路径

PATH:可执行文件在哪里

当你在终端输入ls,系统怎么知道ls这个程序在哪里?就是靠PATH变量。

$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

PATH是一系列目录路径,用冒号分隔。当你输入一个命令,系统会按顺序在这些目录里查找对应的可执行文件。

which python3    # 查看python3在哪个目录
# 输出:/usr/bin/python3

type -a python3  # 查看所有匹配的python3

如果你自己写了一个脚本放在/home/robot/scripts,想直接输入名字就能运行,需要把这个目录加到PATH:

export PATH=$PATH:/home/robot/scripts

这样当前终端就能识别你的脚本了。但要永久生效,需要把这行加到~/.bashrc里。

LD_LIBRARY_PATH:动态库在哪里

程序运行时需要的动态库(.so文件),默认在/usr/lib、/lib这些系统目录里找。如果你自己编译安装了一个库到/opt/mylib/lib,系统默认找不到。

这时候需要设置LD_LIBRARY_PATH:

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/mylib/lib

这样程序运行时就能找到你安装的库了。

查看一个程序依赖哪些动态库:

ldd /usr/bin/python3

如果某个库显示"not found",就是找不到这个动态库,需要设置LD_LIBRARY_PATH或者把库文件放到系统目录。

ROS2的环境变量

ROS2大量使用环境变量。当你source /opt/ros/humble/setup.bash时,实际上设置了这些变量:

# 查看ROS2设置了哪些环境变量
env | grep ROS
env | grep AMENT

关键的几个:

AMENT_PREFIX_PATH:告诉ROS2去哪里找安装的包。

echo $AMENT_PREFIX_PATH
# 输出:/opt/ros/humble

当你编译自己的workspace后,还需要source workspace的setup.bash:

source ~/robot_ws/install/setup.bash

这会把你的workspace路径加到AMENT_PREFIX_PATH里,ROS2才能找到你编译的包。

ROS_DOMAIN_ID:用于隔离同一网络上的不同ROS2系统。默认是0,如果你有两台机器人不想互相干扰,给它们设置不同的DOMAIN_ID:

export ROS_DOMAIN_ID=1

ROS_DISTRO:当前使用的ROS发行版。

echo $ROS_DISTRO
# 输出:humble

永久设置环境变量

临时设置用export,关掉终端就没了。永久设置需要写入配置文件:

# 写入~/.bashrc,只对当前用户生效
echo 'export PATH=$PATH:/home/robot/scripts' >> ~/.bashrc
source ~/.bashrc    # 立即生效

# 写入/etc/environment,对所有用户生效
sudo sh -c 'echo "MY_VAR=value" >> /etc/environment'

配置文件的加载顺序:/etc/profile → ~/.profile → ~/.bashrc。一般推荐把个人配置写在~/.bashrc里。

和机器人开发的关系

ROS2开发中,环境变量几乎无处不在:

编译后找不到包:通常是没source workspace的setup.bash。每次打开新终端都要source,或者把它加到~/.bashrc里。

多个workspace冲突:如果你有多个workspace,source的顺序很重要。后source的会覆盖前面的。一般建议只source你需要的那一个。

动态库找不到:编译时报"cannot find -lxxx",通常是缺少依赖或者LD_LIBRARY_PATH没设置对。用ldd检查可执行文件依赖的库。

ROS2节点找不到:ros2 run找不到你的节点,检查AMENT_PREFIX_PATH是否包含你的workspace路径,检查包是否编译成功。

面试常见考点

"环境变量PATH是什么?"——可执行文件的搜索路径。输入命令时,系统按PATH里的目录顺序查找可执行文件。

"source命令的作用?"——在当前shell环境中执行脚本。和直接执行脚本的区别是,source执行的脚本可以修改当前shell的环境变量,而直接执行是在子shell里,修改不会影响当前shell。

"ROS2为什么要source setup.bash?"——setup.bash设置了AMENT_PREFIX_PATH等环境变量,告诉ROS2去哪里找安装的包和可执行文件。不source的话,ROS2找不到你编译的包。

"临时设置和永久设置环境变量的区别?"——临时设置用export,关掉终端就失效;永久设置写入~/.bashrc或/etc/environment,每次登录都会加载。

网络路由与机器人通信

在机器人系统中,网络路由配置直接影响多机通信的可靠性。一个典型的场景是:机器人通过WiFi连接上位机,同时通过有线网络连接传感器。这时候需要正确配置路由表,确保不同网段的流量走正确的网卡。用ip route查看路由表,用ip route add添加静态路由。在ROS2中,还需要注意多播是否被正确路由,因为DDS依赖多播进行节点发现。

还有一个面试常问的点:子网掩码的作用。子网掩码用来区分IP地址中的网络部分和主机部分,比如255.255.255.0表示前24位是网络号。在机器人多机通信中,正确配置子网掩码是确保设备能互相发现的前提。

给你的建议

环境变量和路径是Linux开发的基础,必须搞明白。几个要点:

PATH决定命令在哪里,LD_LIBRARY_PATH决定动态库在哪里。ROS2的setup.bash本质上就是设置这些路径。

每次打开新终端都要source ROS2的setup.bash,很烦?把它加到~/.bashrc里:

echo "source /opt/ros/humble/setup.bash" >> ~/.bashrc
echo "source ~/robot_ws/install/setup.bash" >> ~/.bashrc

遇到"command not found"或"cannot find library"的错误,先检查PATH和LD_LIBRARY_PATH。90%的问题都是路径没设置对。另外printenv PATH和echo $PATH效果一样,env | grep KEY可以快速过滤特定变量,排查问题时很好用。


上一篇:第91篇 apt与源码编译——Linux软件安装的完整指南

下一篇预告:第93篇 systemd服务管理——让机器人程序开机自启

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐