-n作用
-n 字符串 \] or \[ 字符串 \] 字符串的长度为非零(有内容)则为真。加-n与不加-n结果相同。 ## -z作用 \[ -z 字符串 \] 字符串的长度为零则为真。 字符串为空即NULL时为真,与上面的-n相反。 ## -f作用 \[ -f FILE \] 如果 FILE 存在且是一个普通文件则为真。 ros系统环境为ros2 foxy。 ## 系统自带的包source的第一个系统脚本文件 /opt/ros/foxy/setup.bash ```bash # copied from ament_package/template/prefix_level/setup.bash AMENT_SHELL=bash # source setup.sh from same directory as this file AMENT_CURRENT_PREFIX=$(builtin cd "`dirname "${BASH_SOURCE[0]}"`" && pwd) # trace output if [ -n "$AMENT_TRACE_SETUP_FILES" ]; then echo "# . \"$AMENT_CURRENT_PREFIX/setup.sh\"" fi . "$AMENT_CURRENT_PREFIX/setup.sh" ``` 通过在终端显示这个变量验证,$AMENT_TRACE_SETUP_FILES没有内容。  \[ -n "$AMENT_TRACE_SETUP_FILES" \]没有内容,if fi内代码不运行,直接跳到最后一句执行 ```bash . "$AMENT_CURRENT_PREFIX/setup.sh" ``` 这个脚本文件的意思是运行同一个文件夹内的setup.sh文件,转入运行下面的脚本。 /opt/ros/foxy/setup.sh ```bash # generated from ament_package/template/prefix_level/setup.sh.in # since this file is sourced use either the provided AMENT_CURRENT_PREFIX # or fall back to the destination set at configure time : ${AMENT_CURRENT_PREFIX:=/opt/ros/foxy} # set type of shell if not already set : ${AMENT_SHELL:=sh} # function to append non-duplicate values to environment variables # using colons as separators and avoiding leading separators ament_append_unique_value() { # arguments _listname=$1 _value=$2 #echo "listname $_listname" #eval echo "list value \$$_listname" #echo "value $_value" # check if the list contains the value eval _values=\$$_listname _duplicate= _ament_append_unique_value_IFS=$IFS IFS=":" if [ "$AMENT_SHELL" = "zsh" ]; then ament_zsh_to_array _values fi for _item in $_values; do # ignore empty strings if [ -z "$_item" ]; then continue fi if [ $_item = $_value ]; then _duplicate=1 fi done unset _item # append only non-duplicates if [ -z "$_duplicate" ]; then # avoid leading separator if [ -z "$_values" ]; then eval $_listname=\"$_value\" #eval echo "set list \$$_listname" else # field separator must not be a colon unset IFS eval $_listname=\"\$$_listname:$_value\" #eval echo "append list \$$_listname" fi fi IFS=$_ament_append_unique_value_IFS unset _ament_append_unique_value_IFS unset _duplicate unset _values unset _value unset _listname } # iterate over all parent_prefix_path files _prefix_setup_IFS=$IFS IFS=" " # this variable contains the concatenated prefix paths in reverse order _UNIQUE_PREFIX_PATH="" # this check is used to skip parent prefix path in the Debian package if [ -z "SKIP_PARENT_PREFIX_PATH" ]; then # find parent prefix path files for all packages under the current prefix _RESOURCES="$(\find "$AMENT_CURRENT_PREFIX/share/ament_index/resource_index/parent_prefix_path" -mindepth 1 -maxdepth 1 2> /dev/null | \sort)" if [ "$AMENT_SHELL" = "zsh" ]; then ament_zsh_to_array _RESOURCES fi for _resource in $_RESOURCES; do # read the content of the parent_prefix_path file _PARENT_PREFIX_PATH="$(\cat "$_resource")" # reverse the list _REVERSED_PARENT_PREFIX_PATH="" IFS=":" if [ "$AMENT_SHELL" = "zsh" ]; then ament_zsh_to_array _PARENT_PREFIX_PATH fi for _path in $_PARENT_PREFIX_PATH; do # replace placeholder of current prefix if [ "$_path" = "{prefix}" ]; then _path="$AMENT_CURRENT_PREFIX" fi # avoid leading separator if [ -z "$_REVERSED_PARENT_PREFIX_PATH" ]; then _REVERSED_PARENT_PREFIX_PATH=$_path else _REVERSED_PARENT_PREFIX_PATH=$_path:$_REVERSED_PARENT_PREFIX_PATH fi done unset _PARENT_PREFIX_PATH # collect all unique parent prefix path if [ "$AMENT_SHELL" = "zsh" ]; then ament_zsh_to_array _REVERSED_PARENT_PREFIX_PATH fi for _path in $_REVERSED_PARENT_PREFIX_PATH; do ament_append_unique_value _UNIQUE_PREFIX_PATH "$_path" done unset _REVERSED_PARENT_PREFIX_PATH done unset _resource unset _RESOURCES fi # append this directory to the prefix path ament_append_unique_value _UNIQUE_PREFIX_PATH "$AMENT_CURRENT_PREFIX" unset AMENT_CURRENT_PREFIX # store AMENT_SHELL to restore it after each prefix _prefix_setup_AMENT_SHELL=$AMENT_SHELL # source local_setup.EXT or local_setup.sh file for each prefix path IFS=":" if [ "$AMENT_SHELL" = "zsh" ]; then ament_zsh_to_array _UNIQUE_PREFIX_PATH fi for _path in $_UNIQUE_PREFIX_PATH; do # trace output if [ -n "$AMENT_TRACE_SETUP_FILES" ]; then echo "# . \"$_path/local_setup.$AMENT_SHELL\"" fi if [ -f "$_path/local_setup.$AMENT_SHELL" ]; then if [ "$AMENT_SHELL" = "sh" ]; then # provide AMENT_CURRENT_PREFIX to .sh files AMENT_CURRENT_PREFIX=$_path fi # restore IFS before sourcing other files IFS=$_prefix_setup_IFS . "$_path/local_setup.$AMENT_SHELL" # restore AMENT_SHELL after each prefix-level local_setup file AMENT_SHELL=$_prefix_setup_AMENT_SHELL fi done unset _path IFS=$_prefix_setup_IFS unset _prefix_setup_IFS unset _prefix_setup_AMENT_SHELL unset _UNIQUE_PREFIX_PATH unset AMENT_SHELL ``` ## 我们自己生成的包source环境变量脚本 工作空间内 source install/setup.bash ```bash # generated from colcon_bash/shell/template/prefix_chain.bash.em # This script extends the environment with the environment of other prefix # paths which were sourced when this file was generated as well as all packages # contained in this prefix path. # function to source another script with conditional trace output # first argument: the path of the script _colcon_prefix_chain_bash_source_script() { if [ -f "$1" ]; then if [ -n "$COLCON_TRACE" ]; then echo ". \"$1\"" fi . "$1" else echo "not found: \"$1\"" 1>&2 fi } # source chained prefixes # setting COLCON_CURRENT_PREFIX avoids determining the prefix in the sourced script COLCON_CURRENT_PREFIX="/opt/ros/foxy" _colcon_prefix_chain_bash_source_script "$COLCON_CURRENT_PREFIX/local_setup.bash" # source this prefix # setting COLCON_CURRENT_PREFIX avoids determining the prefix in the sourced script COLCON_CURRENT_PREFIX="$(builtin cd "`dirname "${BASH_SOURCE[0]}"`" > /dev/null && pwd)" _colcon_prefix_chain_bash_source_script "$COLCON_CURRENT_PREFIX/local_setup.bash" unset COLCON_CURRENT_PREFIX unset _colcon_prefix_chain_bash_source_script ``` $0当前脚本名 $1 脚本的第一个参数 _colcon_prefix_chain_bash_source_script(){}函数的意思是第一个参数文件存在就运行第一个参数,没有就报错。 所以我们在自己的工作空间source install/setup.bash相当于同时source /opt/ros/foxy/local_setup.bash source install/local_setup.bash