ROS 中setup.bash

版权声明:学习记录~ https://blog.csdn.net/robinhjwy/article/details/79597095

好久没写了,最近搞了辆小车,瞅了瞅ROS的相关内容,没有写ROS的内容,刚开始看,写的话基本就成了书本粘贴。。。不过最近由ROS引出来的一些Linux相关的东西,然后又回头撸了撸私房菜,还是有一些收获的。

先说一下此篇的起因,就是在创建了ROS 的workspace之后,需要将workspace中的setup.bash文件写入~/.bashrc 文件中,让其启动:
就像这个样子:

source /opt/ros/kinetic/setup.bash

这句的目的就是在开新的terminal的时候,运行这个setup.bash,而这个setup.bash的作用是让一些ROS* 开头的命令可以使用。同时还能够创建一些ROS开头的环境变量,比如:

ROS_PACKAGE_PATH

这个环境变量是一堆路径字符串:

ROS_PACKAGE_PATH="/opt/ros/kinetic/share"

用来表征ROS功能包路径,当你使用:

rospack find {packagename}

搜寻功能包所在的路径时,它会依据ROS_PACKAGE_PATH 所提供的功能包路径里去寻找,不在这个环境变量里的路径就不会去寻找了,即便你有这个功能包,也会显示找不到。

继续捯饬的过程中发现这么个现象:
假如我在~/.bashrc中加入这么一堆的source:

source /opt/ros/kinetic/setup.bash

source ~/catkin_ws/devel/setup.bash
source ~/robin_ws/devel/setup.bash

source ~/riki/tySDK/camport_ros-master/devel/setup.bash
source ~/riki/catkin_ws/devel/setup.bash

本来以为ROS_PACKAGE_PATH 会依次增加,把每一个功能包的路径都添加上,但是发现不是,貌似会有干扰。就是只有第一句的时候,ROS_PACKAGE_PATH="/opt/ros/kinetic/share" 加上后面的之后会变化,并不是加一句,增加一条,而是没有什么规律。。。
比如我只有这两句:

source /opt/ros/kinetic/setup.bash
source ~/catkin_ws/devel/setup.bash

的时候ROS_PACKAGE_PATH 是这样的:

robin@robin:~$ echo $ROS_PACKAGE_PATH
/home/robin/catkin_ws/src:/home/robin/robin_ws/src:/home/robin/riki/tySDK/camport_ros-master/src:/opt/ros/kinetic/share

但是,我再加一句:

source /opt/ros/kinetic/setup.bash

source ~/catkin_ws/devel/setup.bash
source ~/robin_ws/devel/setup.bash

再source一下:

robin@robin:~$ echo $ROS_PACKAGE_PATH
/home/robin/robin_ws/src:/home/robin/riki/tySDK/camport_ros-master/src:/opt/ros/kinetic/share

我的/home/robin/catkin_ws/src 竟然没了?!
一头雾水,猜测是不是这样source好多,他们之间会干扰,于是打开上面的setup.bash文件,看看究竟:

#!/usr/bin/env bash
# generated from catkin/cmake/templates/setup.bash.in

CATKIN_SHELL=bash

# source setup.sh from same directory as this file
_CATKIN_SETUP_DIR=$(builtin cd "`dirname "${BASH_SOURCE[0]}"`" > /dev/null && pwd)
. "$_CATKIN_SETUP_DIR/setup.sh"

整个_CATKIN_SETUP_DIR 其实就是获得当前正在执行的脚本的所在路径,然后第二句执行一下同路径下的setup.sh文件。
主要来解析一下这一句:

_CATKIN_SETUP_DIR=$(builtin cd "`dirname "${BASH_SOURCE[0]}"`" > /dev/null && pwd)

一步步拆解:
1、首先最内层的:${BASH_SOURCE[0]}
参见:https://www.cnblogs.com/sunfie/p/5943979.html
总体来说就是:BASH_SOURCE[0] , 取得当前执行的shell文件所在的路径及文件名。
举个栗子:比如你在~/test中有个test.sh文件,文件中有这么一句:echo ${BASH_SOURCE[0]}
运行结果是这样的:

robin@robin:~$ ./test/test.sh 
./test/test.sh

会输出路径加文件名。

2、"${BASH_SOURCE[0]}"
这句会把双引号内的东西全部转换成字符串。不过这里貌似${BASH_SOURCE[0]} 的结果输出本身就是字符串吧。。。

3、dirname "${BASH_SOURCE[0]}"
参考:http://man.linuxde.net/dirname
总结就是去除字符串中的文件名称,只留路径部分。测试一哈,还是我们的~/test中有个test.sh文件,文件中之前的那句改一改:

echo `dirname ${BASH_SOURCE[0]}`

输出结果变为:

robin@robin:~$ ./test/test.sh
./test

只有test.sh所在的路径了。

3

`dirname "${BASH_SOURCE[0]}"`

这步比上面多了对反引号。
参考:http://blog.csdn.net/jackyechina/article/details/52813007
总结就是:【`】,学名叫“倒引号”, 如果被“倒引号”括起来, 表示里面需要执行的是命令。
因为整个整体在双引号中,若不夹这个反引号,diename会被变成字符串,加上倒引号后,表征倒引号中的内容是一行命令,主要是指dirname命令

"`dirname "${BASH_SOURCE[0]}"`"

4

builtin cd "`dirname "${BASH_SOURCE[0]}"`"

参看:http://man.linuxde.net/builtin
主要意思就是使用shell内建的cd命令进入当前脚本所在的目录。

5

builtin cd "`dirname "${BASH_SOURCE[0]}"`" > /dev/null

此步多了个 > /dev/null
参看:https://zhidao.baidu.com/question/223779994.html
大概意思就是不要输出任何东西吧,我猜的。。。

6

&&

参看:http://blog.csdn.net/a627088424/article/details/20360107
前一条执行成功后,执行后面的命令。

7 pwk
参看:http://man.linuxde.net/pwd
显示用户当前工作目录的绝对路径。

_CATKIN_SETUP_DIR=$(builtin cd "`dirname "${BASH_SOURCE[0]}"`" > /dev/null && pwd)

所以整个语句流程就是取得本shell的绝对路径和名称,然后dirname去掉名称只留路径,然后进入此路径,同时将cd 的输出扔掉,不予显示。然后这步执行成功的话pwk出绝对路径然后赋值给_CATKIN_SETUP_DIR变量。

巴特!搞了这么久貌似还是没有找到为什么source之间会干扰。。。
后来又查询到底如何正规的修改环境变量:

export ROS_PACKAGE_PATH=${ROS_PACKAGE_PATH}:/home/robin/catkin_ws/src

直观上就是将环境变量再赋值一下,并在后面接上一段。。。

猜你喜欢

转载自blog.csdn.net/robinhjwy/article/details/79597095