ROS工作空间环境变量配置详解:从source原理到实战排查 很多刚开始碰 ROS 的朋友都会在同一个地方卡住明明按照教程一步步装好了 ROS也建好了工作空间一关终端再打开rosrun就报“找不到包”或者roscore直接提示“command not found”。这时候十有八九就是环境变量没配好。我当年在 Ubuntu 上折腾 ROS 时也被这个问题折磨过后来把 ROS 的环境变量机制彻底搞明白了才发现这其实不难只是很多教程没有把背后的逻辑讲透。这篇文章我就把 ROS 工作空间环境变量配置这件事掰开揉碎讲清楚它到底是怎么工作的、为什么每次都要 source、如何一劳永逸地配置好、以及最常见的坑和排查方法。内容尽量照顾到新手但也会有对进阶用户有用的细节比如多工作空间叠加、Zsh 环境的差异、环境变量残留清理等。1. 工作空间与环境变量先搞清楚它们各自扮演什么角色1.1 一个 ROS 工作空间里到底有什么ROS 的工作空间业内通常叫 catkin workspace本质上就是一个有特定目录结构的文件夹。当你用mkdir -p ~/catkin_ws/src创建它再用catkin_make编译之后这个文件夹里会多出build和devel两个目录。这三个目录各司其职src存放功能包源码的地方你自己写的包、从网上 clone 下来的包都在这里。build编译过程中产生的中间文件相当于 C 项目里的 obj 目录一般不需要手动去动它。devel编译产物的“安装区”里面存放生成的可执行文件、动态库、头文件还有一个极其关键的setup.bash文件。很多教程会告诉你“编译完了记得 source 一下”但没解释为什么要这么做。其实关键在于你编译好的可执行文件、库文件都散落在devel目录的各处而系统默认是不知道这些东西在哪里的。如果你不告诉系统去哪里找它们那rosrun自然找不到你的节点roslaunch也会报错。环境变量就是这个“告诉系统去哪里找”的机制。1.2 环境变量在 ROS 里承担什么样的角色ROS 的运行严重依赖环境变量。你可以把环境变量想象成一个随身携带的通讯录ROS 里的各种工具命令每次启动时都会先去翻这本通讯录搞清楚该去哪里找功能包、去哪里找共享库、去哪里找节点。最核心的几个 ROS 环境变量包括ROS_PACKAGE_PATH告诉 ROS 去哪里搜索功能包。当你使用rospack find或rosrun时系统按这个路径列表逐个查找。CMAKE_PREFIX_PATHcatkin 编译系统用它来寻找已经编译好的包。这个变量会被 catkin 自动管理。ROS_DISTRO记录当前使用的 ROS 发行版比如 noetic、melodic、foxy。ROS_MASTER_URI在多机通信时特别重要记录 roscore 主节点的地址和端口。LD_LIBRARY_PATH系统的动态链接库搜索路径ROS 编译出来的 .so 文件需要靠它才能被正确加载。PYTHONPATHROS 里 Python 写的节点和库靠这个变量找到它们的路径。这些变量不是凭空出现的而是由每个工作空间编译之后生成的setup.bash脚本负责设置。每次执行source devel/setup.bash就是运行这个脚本把上述变量重新赋值一遍。这样你新编译的包、新生成的链接库就都被“注册”到当前终端的环境里了。注意早期 ROS 1 使用 rosbuild 构建系统时还有个ROS_ROOT之类的变量现在用 catkin 后这些变量大多合并或者被替代了。如果你在网上看到比较老的文章还在介绍这些变量名不用太纠结看env | grep ROS输出里的实际内容即可。1.3 为什么刚编译完必须 source重启终端又失效了这是个被问了无数遍的问题。答案其实很简单source这个命令只对当前终端会话生效。你每次新开一个终端终端进程会继承系统级和用户级的初始化配置但你在上一个终端会话里手动执行source设置的那些变量并不会被新终端继承。换句话说终端环境是“一次性”的。你手动设置的变量随着终端关闭就被系统回收了。所以如果想让配置永久生效就必须把source这行命令写进 shell 的启动脚本里让每个新终端一启动就自动执行它。在 Ubuntu 默认的 Bash 环境下这个文件是~/.bashrc。这个机制其实和 Windows 下设置系统环境变量是类似的只是 ROS 更倾向于用“每次启动时叠加”的方式而不是写死在系统注册表里。这样做的好处是灵活——你可以方便地在多个工作空间之间切换不用担心改系统配置影响全局。2. 核心原理拆解setup.bash 到底做了什么2.1 source 命令与普通执行的区别很多人对source这个命令的理解停留在“运行脚本”的层面但它和./setup.bash这种执行方式有一个本质区别source会在当前 shell 进程里直接执行脚本内容脚本里设置的环境变量会留在当前进程中而./setup.bash会创建一个子进程来运行脚本脚本里设置的变量只对这个子进程有效子进程退出后变量就消失了。用一个类比来解释source像是你直接在自己的办公桌上翻看一份资料看完把内容记在自己脑子里而./setup.bash像是你让一个同事去隔壁房间看资料看完他记住了但你什么都没记住。ROS 的 setup.bash 脚本里边其实就是一堆 export 语句。它先读取你自己设置的路径环境然后在此基础上追加 ROS 相关的路径。核心逻辑大致如下# setup.bash 中简化后的逻辑示意 export ROS_PACKAGE_PATH/home/yourname/catkin_ws/src:/opt/ros/noetic/share export CMAKE_PREFIX_PATH/home/yourname/catkin_ws/devel:/opt/ros/noetic export LD_LIBRARY_PATH/home/yourname/catkin_ws/devel/lib:/opt/ros/noetic/lib export PYTHONPATH/home/yourname/catkin_ws/devel/lib/python3/dist-packages:/opt/ros/noetic/lib/python3/dist-packages当然实际脚本的逻辑更复杂还包含对已有变量的去重、拼接等处理但核心思路就是把你工作空间的路径追加到系统 ROS 路径之前。这样就实现了“优先找用户编译的包找不到再找系统自带的包”的效果。2.2 setup.bash、setup.sh、setup.zsh 三者怎么选每个 compiles 完的工作空间里devel目录下其实会生成多个不同后缀的 setup 文件。常见的有setup.bash、setup.sh、setup.zsh。它们的核心作用一样只是面向的 shell 类型不同setup.bash面向 Bash shellUbuntu 默认终端就是 Bash所以用这个最多。setup.shPOSIX shell 的通用版本是最基础的实现其他脚本通常会调用它。setup.zsh面向 Zsh shell。如果你用了 oh-my-zsh 这类工具默认 shell 是 Zsh那么就要 source 这个文件。重点来了如果你默认 shell 是 Zsh却在 .zshrc 里写入了source /opt/ros/noetic/setup.bash理论上也能工作因为 setup.bash 最终会调用 setup.sh但更稳妥的做法是使用对应的 setup.zsh避免潜在的兼容问题。我见过一些人把系统默认 shell 从 Bash 改成 Zsh 后ROS 命令全部失效就是因为 .zshrc 里没有配置 ROS 环境而 .bashrc 里的配置对 Zsh 根本不生效。2.3 系统级工作空间与用户级工作空间的叠加关系安装 ROS 时安装包会在/opt/ros/noetic/目录下创建一个系统级的工作空间里面也有一套 setup.bash。所以你经常看到教程里有两行 sourcesource /opt/ros/noetic/setup.bash source ~/catkin_ws/devel/setup.bash第一行加载 ROS 系统自带的全部功能包第二行叠加你自己工作空间的包。这两个不是取代关系而是叠加关系。ROS 的环境变量是支持多路径共存的路径之间用冒号分隔搜索时按从左到右的顺序查找。这就是为什么你把自己的功能包放在~/catkin_ws/src下编译后rospack find能找到它而如果没 source 自己的工作空间它就只能找到/opt/ros/noetic下的系统包。这两个 source 的执行顺序有一个小门道自己的工作空间放在后面执行最后生成的路径列表中自己的工作空间会排在前面这样如果有同名功能包优先找到你自己编译的版本。这在做二次开发或者替换官方包时非常有用。3. 实操配置全过程从零到一配好环境变量3.1 创建工作空间并编译在配置环境变量之前先讲讲工作空间怎么创建。虽然网上教程很多但有不少朋友在第一步就踩坑比如在src目录里直接跑catkin_make或者把工作空间建到路径带中文的目录下后面各种奇怪的编译错误就来了。建议按这个流程走# 创建目录结构 mkdir -p ~/catkin_ws/src cd ~/catkin_ws/src # 初始化工作空间生成 CMakeLists.txt 软链接 catkin_init_workspace # 回到工作空间根目录编译 cd ~/catkin_ws catkin_make第一次编译成功后~/catkin_ws下会出现build和devel两个目录。这时候你检查一下devel目录下是不是有setup.bash文件有的话就说明环境准备文件已经生成了。这里给大家两个建议一是工作空间路径尽量不要有中文和空格ROS 的构建工具对这类路径的处理不太好二是catkin_make需要在包含src目录的上级目录运行也就是在~/catkin_ws下运行不是在src里运行这一点新手很容易搞错。3.2 手动 source 验证环境是否正常编译完成之后先不要急着写进配置文件先手动在当前终端里 source 一次确认环境能正常加载。这一步的好处是如果出问题你能明确知道是编译环节的问题还是环境配置的问题。source devel/setup.bash执行完后用下面几个命令验证环境变量是否正确# 打印所有和 ROS 相关的环境变量 env | grep ROS # 检查能否找到自己的功能包 rospack find your_package_name # 检查 ROS 版本 rosversion -d正常情况下echo $ROS_PACKAGE_PATH会输出类似下面这样其中前半部分是你自己的工作空间路径/home/yourname/catkin_ws/src:/opt/ros/noetic/share如果能看到这个输出说明当前工作空间的环境已经生效了。这时候你在另一个终端窗口运行roscore再在当前终端运行自己写的节点就能正常通信了。3.3 写入 Bash 启动脚本实现开机自动生效手动 source 只是临时有效关掉终端就没了。要让配置永久生效需要把 source 命令追加到~/.bashrc文件里。推荐的做法是用echo命令追加而不是用编辑器手动打开文件这样不容易破坏原有的文件内容。echo source /opt/ros/noetic/setup.bash ~/.bashrc echo source ~/catkin_ws/devel/setup.bash ~/.bashrc注意这里如果你用的是 ROS 2比如 Humble那么安装路径是/opt/ros/humble/setup.bash不要写错。写完之后执行source ~/.bashrc让当前终端立刻生效或者直接关掉终端重开一个。这里有一个重要的顺序问题系统级的 source 必须写在用户级的前面。因为用户级的工作空间是在系统级基础上叠加的如果顺序反了最后环境变量里路径的顺序会不对可能导致系统包优先于用户包被找到。虽然大多数情况下不影响使用但在包名冲突时会带来隐蔽的问题。3.4 Zsh 用户怎么配置如果你用的是 Zsh那就不能靠修改~/.bashrc了因为 Zsh 启动时不会读取.bashrc它读的是~/.zshrc。需要执行echo source /opt/ros/noetic/setup.zsh ~/.zshrc echo source ~/catkin_ws/devel/setup.zsh ~/.zshrc注意后缀变成了.zsh。如果你之前的.bashrc里已经写入了 source 语句现在转用 Zsh那些配置是完全不会生效的。这也是为什么很多人“明明配好了环境变量换了终端又失效”的隐藏原因之一。检测当前 shell 类型可以用echo $SHELL输出/bin/bash说明是 Bash输出/usr/bin/zsh说明是 Zsh。配好之后重新打开一个终端窗口运行rosversion -d验证能否正确输出版本号。4. 多工作空间与多版本 ROS 的环境变量管理4.1 叠加工作空间多个工作空间怎么共存做实际项目时你很可能不止一个工作空间。比如有一个用于学习测试的~/catkin_ws还有一个公司项目的~/project_ws。这两个工作空间如果都想在当前终端使用最简单的方式是把它们的 setup 文件都 source 一遍source ~/catkin_ws/devel/setup.bash source ~/project_ws/devel/setup.bash此时环境变量里会同时包含两个工作空间的路径而且后 source 的project_ws会排在前面。这意味着如果在两个工作空间里有同名的功能包优先找到的是后 source 的那个。这个特性有时候很有用比如你想用自己的修改版本覆盖官方包时把你的工作空间放在后面 source 就行。但反过来如果你没有意识到自己不小心写了两个同名包就可能出现“我明明改了代码但 rosrun 跑的还是旧版”的诡异现象。排查方法也很简单运行rospack find 包名看返回路径是哪个如果发现路径不是你想象中的那个工作空间说明有同名包冲突需要调整 source 顺序或者删除其中一个。4.2 多版本 ROS 共存的环境变量切换有些朋友机器上同时装了 ROS 1 和 ROS 2或者装了多个 ROS 发行版比如 melodic 和 noetic。这种情况下环境变量冲突的概率非常高因为两者都依赖ROS_DISTRO、CMAKE_PREFIX_PATH等变量只是路径不同。我见过最典型的场景是想用 ROS 1但终端里rosversion -d显示的是 ROS 2 的版本或者roscore命令直接找不到。这通常是因为.bashrc里把多个版本的 source 都写上去了后写的覆盖了前面版本的设置但部分变量又没有完全清理干净导致环境“不伦不类”。推荐的做法是不要把所有版本的 source 都写进.bashrc。可以写一个切换脚本比如创建~/ros_env_switch.sh#!/bin/bash alias ros1source /opt/ros/noetic/setup.bash echo Switched to ROS Noetic alias ros2source /opt/ros/humble/setup.bash echo Switched to ROS 2 Humble然后在.bashrc里 source 这个脚本文件。使用时打开新终端先执行ros1或ros2来选择版本。这个方案的思路很简单系统级环境变量不用固定写死按需加载避免冲突。如果你只是偶尔用 ROS 2更简单的方法是在~/.bashrc里只 source ROS 1需要 ROS 2 时在当前终端手动 source 一次。4.3 清理残留环境变量删除工作空间后如何恢复正常有朋友问过一个问题我把一个工作空间整个删掉了结果每次新终端打开 ROS 都报错报错内容还指向那个已经不存在的路径。这就是因为.bashrc里的 source 语句还指向那个路径每次启动终端都会尝试 source 一个不存在的文件。解决办法有两个一是把.bashrc里对应的 source 行删掉二是保留 source 语句但用test -f判断文件是否存在存在才 source。第二种方法更稳健也是我比较推荐的做法。可以在.bashrc里这样写if [ -f /opt/ros/noetic/setup.bash ]; then source /opt/ros/noetic/setup.bash fi if [ -f ~/catkin_ws/devel/setup.bash ]; then source ~/catkin_ws/devel/setup.bash fi这样即使工作空间被删除了也不会因为 source 失败而报警终端还能正常启动。这个方法也适用于团队协作的场景——别人拉取你的配置脚本时即使他的开发目录结构和你的不完全一样也不会直接报错。5. 高频问题与排查技巧实录5.1 新终端找不到功能包怎么办这是环境变量问题里最常见的一种。现象是新开终端后rosrun my_package my_node报错package my_package not found但上一个终端里运行得好好的。排查步骤按顺序来先执行echo $ROS_PACKAGE_PATH看看有没有包含你的工作空间路径。如果没有说明.bashrc里的 source 没写对或者没生效。执行ls ~/catkin_ws/devel/setup.bash确认文件存在。如果不存在说明工作空间没有编译成功需要回到~/catkin_ws重新执行catkin_make。检查.bashrc里的路径是否写对了比如用户名是否写错、路径是不是/root/catkin_ws而实际你用的是普通用户。执行source ~/.bashrc让当前的终端生效或者干脆关掉终端重开。这里有个经验技巧新终端里如果连roscore都提示找不到命令那大概率是系统级 ROS 环境都没配好先检查/opt/ros/noetic/setup.bash是否被正确 source。如果roscore正常但rosrun找不到包那才是工作空间级配置的问题。5.2 source 了还是找不到节点这种情况更隐蔽你明明手动执行了source devel/setup.bashecho $ROS_PACKAGE_PATH也显示有你的工作空间路径但rosrun照样找不到节点。遇到这种问题先别急思考一下你写的my_node编译出可执行文件了吗有时候catkin_make成功了但你的 CMakeLists.txt 配置不对没有生成可执行文件或者生成的路径不对。执行这个命令确认find ~/catkin_ws/devel -name my_node如果找不到可执行文件说明问题出在编译配置上而不是环境变量上。常见原因是 CMakeLists.txt 里忘记写add_executable和target_link_libraries或者catkin_package()的配置缺失。这种时候先解决编译问题环境变量反而是正常的。还有一种可能是你的包名和节点名不一致。rosrun的语法是rosrun 包名 节点名如果你建包时包名叫my_pkg节点名叫my_node执行rosrun my_pkg my_node才对。如果你写成rosrun my_node my_node那当然找不到包。5.3 Python 节点报找不到模块的问题ROS 里写 Python 节点的人很多经常遇到一个场景节点本身找到了但运行时报ModuleNotFoundError: No module named my_ros_pkg。这通常是PYTHONPATH环境变量的问题。在 catkin 工作空间里Python 模块会被安装到devel/lib/python3/dist-packages目录如果你的PYTHONPATH没有包含这个路径Python 就找不到你的模块。用下面命令验证echo $PYTHONPATH正常输出里应该包含/home/yourname/catkin_ws/devel/lib/python3/dist-packages:/opt/ros/noetic/lib/python3/dist-packages如果没有重新 source 一次setup.bash。如果还是没有检查你是否用了虚拟环境比如 conda、venv虚拟环境会重写 PYTHONPATH导致系统的 ROS Python 路径被覆盖。这是我在实际项目中踩过的坑在 conda 环境里跑 ROS 的 Python 节点经常因为 Python 版本冲突导致各种奇怪问题。建议 ROS 项目尽量用系统 Python或者为每个节点单独创建虚拟环境并在源码里显式指定解释器。5.4 环境变量一直不对多个配置文件互相覆盖有些用户同时配置了~/.bashrc、~/.profile、~/.bash_profile每个文件里都加了自己的 ROS 配置结果这些配置互相覆盖最终环境变量混乱不堪。这里要搞清楚 Ubuntu 下这些文件的加载顺序登录 shell比如通过 SSH 登录先读/etc/profile再读~/.profile然后是~/.bash_profile。非登录交互式 shell比如在桌面环境里打开终端读~/.bashrc。这意味着如果你在~/.bashrc里设置了 ROS 环境又在~/.profile里设置了不同的 ROS 环境SSH 登录时.profile的配置会覆盖.bashrc的效果但本地打开终端时.bashrc的配置又生效。这就造成了“时好时坏”的诡异现象。我的建议是ROS 环境统一写在~/.bashrc里不要往~/.profile或~/.bash_profile里写。删除其他文件里的重复配置保持单一配置源。很多“环境变量没生效”的求助帖最后都是这个原因。6. 进阶技巧用 alias 和脚本提升环境管理效率6.1 把常用的 source 命令封装成 alias如果你的工作流比较固定可以在.bashrc里加一些 alias 来简化操作。比如alias cwcd ~/catkin_ws alias cssource ~/catkin_ws/devel/setup.bash alias cmcd ~/catkin_ws catkin_make这样每次编译完一句cs就能重新加载环境不用敲一长串路径。如果你有多个工作空间也可以给每个工作空间加一个专属的 aliasalias cs_projectsource ~/project_ws/devel/setup.bash这种写法在多人协作时特别实用大家把一份自定义配置脚本放到团队仓库里clone 下来后 source 一下环境就全部就绪。6.2 用 env 命令快速诊断环境问题遇到环境变量问题我第一反应永远是执行这个命令env | grep -E ROS|CMAKE|PYTHON把输出拿到手就能判断问题出在哪个环节。比如ROS_PACKAGE_PATH为空说明工作空间级的 setup 没被加载ROS_MASTER_URI指向了错误的 IP说明多机通信配置有问题CMAKE_PREFIX_PATH里没有工作空间路径说明 catkin 环境没加载成功。整理成一个速查表就是下面这个样子现象可能原因排查命令找不到功能包工作空间 setup 未加载echo $ROS_PACKAGE_PATH找不到节点CMakeLists 未生成可执行文件find devel -name 节点名Python 模块找不到PYTHONPATH 未包含 devel 目录echo $PYTHONPATHroscore 都找不到系统级 ROS 环境未配置source /opt/ros/noetic/setup.bash版本显示不对多个 ROS 版本环境冲突echo $ROS_DISTRO6.3 为团队准备环境初始化脚本如果你需要帮同事或者团队成员快速配置环境写一个初始化脚本是效率最高的方式。下面是一个适用于 ROS Noetic 的脚本示例放在团队仓库根目录#!/bin/bash # 检查 ROS 环境目录 if [ -d /opt/ros/noetic ]; then source /opt/ros/noetic/setup.bash else echo -e \033[31mROS Noetic 未安装请先安装 ROS\033[0m return 1 fi # 检查工作空间 if [ -f $HOME/catkin_ws/devel/setup.bash ]; then source $HOME/catkin_ws/devel/setup.bash else echo -e \033[33m未找到 ~/catkin_ws 工作空间跳过工作空间环境配置\033[0m fi脚本的好处是可以根据实际情况灵活判断比如工作空间存在才 source不存在就提示但不中断。使用者只需要在.bashrc里加一行source ~/team_ws/env_setup.sh以后团队里任何人更新了环境配置都只需要更新仓库里的脚本所有成员重新打开终端后就能自动同步不用逐个通知。这种管理方式在小团队里非常实用比每个人手动在.bashrc里加一堆路径要干净得多。7. 个人实操经验与避坑心得7.1 关于“为什么教程总让我 source 一次”的个人理解我最初总觉得每次编译完都要 source 一次很麻烦后来才明白这是 ROS 设计上的一个特色也算是一种取舍。catkin 的工作空间没有像 Windows 那样把路径写进系统注册表而是把环境信息集中在每个工作空间的 setup 脚本中这带来一个好处你可以在同一台机器上维护多个互不干扰的工作空间想用哪个就 source 哪个。如果所有路径都写死在系统配置里反而容易冲突。理解了这一点之后我不再觉得 source 麻烦反而把它当成一种“切换项目环境”的操作。每次新开一个终端我都会想一下我现在要操作哪个工作空间然后用对应的 alias 或命令加载它。这样思维上更清晰实际操作中也不容易搞混不同的项目。7.2 一个能帮你节省大量时间的排查顺序如果你在自己的机器上按照网上教程一步步操作依然遇到环境问题我建议按照这个顺序排查亲测有效率很高第一步确认 ROS 本体已正确安装。执行source /opt/ros/noetic/setup.bash roscore如果这一步都不行后边全免谈。第二步确认工作空间编译成功。catkin_make执行完没有任何红色报错且devel/setup.bash文件存在。第三步确认当前终端加载了正确的环境。执行echo $ROS_PACKAGE_PATH确认包含自己的工作空间路径。第四步确认.bashrc配置正确。重新打开终端再看一次环境变量。如果新终端和手动 source 的结果不一样检查.bashrc的内容和加载顺序。第五步如果上面都没问题检查自己的包本身是否编译出了问题。这一步往往被卡在环境变量问题上的人忽略比如 CMakeLists.txt 配置错误导致没有生成可执行文件。大部分环境变量问题在这五步之内都能找到答案。如果你排查到第五步才发现不是环境问题建议回到包编译的环节去调整 CMakeLists.txt而不是继续纠结环境变量。7.3 关于 ROS 2 和鱼香 ROS 等工具的说明有些朋友可能在搜索时看到“鱼香 ROS”以及一些 ROS 2 的安装工具。ROS 2 和 ROS 1 在环境变量管理上有比较大的差异ROS 2 更多地使用AMENT_PREFIX_PATH来代替 ROS 1 的ROS_PACKAGE_PATH。如果你装的 ROS 2配置环境的方式会稍有不同source /opt/ros/humble/setup.bash source ~/ros2_ws/install/setup.bash注意 ROS 2 编译后的环境文件在install目录下而不是devel目录。这是因为 ROS 2 默认使用colcon构建工具它的布局和 catkin 不同。如果你从 ROS 1 转到 ROS 2这个变化是第一个需要适应的。至于“一键安装”类的工具我个人的看法是它们确实能节省安装时间减少路径配置的挫败感但使用这类工具之后你仍然需要理解环境变量的机制因为工作空间的编译、加载、调试都离不开环境变量的正确配置。工具能帮你装好 ROS但帮不了你完成自己的机器人项目。基础概念越扎实后面遇到问题越容易定位。环境变量配置这件事说穿了不算复杂就是“编译产物放在哪系统去哪找”的问题。但正因为简单很多人反而不重视出了问题才想起来翻配置。我希望通过这篇文章你能彻底理解 ROS 环境变量的工作逻辑而不是死记硬背几条命令。以后不管是配置新工作空间、切换 ROS 版本还是帮别人排查环境问题你都能有自己的判断不再被各种教程里的“玄学步骤”带着跑。