我正在做一个安装 ros 的脚本,安装后,用 catkin_make 编译一个工作区。
我找到了解决问题的方法,但我无法解释原因。我有一个名为 install.bash 的文件正在调用其他文件:
#!/bin/bash
source 01_install_ros.bash
重要的是在01_install_ros.bash
中:
# variable not set because it is done in the script setup.bash of ros
echo "before source in 01_install_ros"
echo "ROS_ROOT: "$ROS_ROOT
whereis catkin_make
echo ""
echo "source /opt/ros/kinetic/setup.bash" >> $HOME/.bashrc
# doesn't set the variables
source "$HOME"/.bashrc
# the solutions
source /opt/ros/kinetic/setup.bash
# variables not set if I use the source of .bashrc
echo "after source in 01_install_ros"
echo "ROS_ROOT: "$ROS_ROOT
whereis catkin_make
echo ""
正如评论中所写,采购 .bashrc 而不是直接 setup.bash 是行不通的。我真的不明白为什么。你能解释一下吗?
最佳答案
一些平台带有一个 ~/.bashrc
,它在顶部有一个条件,如果发现 shell 非交互式则明确停止处理 - 尽管 bash
仅在交互式(非登录) session 中自动获取 ~/.bashrc
。
例如,在 Ubuntu 18.04 上:
# If not running interactively, don't do anything
case $- in
*i*) ;;
*) return;;
esac
类似的测试,见于同一平台的/etc/bash.bashrc
:
# If not running interactively, don't do anything
[ -z "$PS1" ] && return
如果是这种情况,脚本中的采购~/.bashrc
将没有效果,因为脚本在中运行默认情况下为非交互式 shell。
您的选项是:
或者:在
中停用条件~/.bashrc
或者:尝试在调用
source ~/.bashrc
之前模拟交互式 shell。
所需的具体仿真取决于条件的具体情况,但有两种可能的方法;如果您事先不知道会遇到哪个条件,则可能必须两者都使用它们:set -i
临时使$-
包含i
,表示交互式 shell。- 如果您知道执行交互性测试的行的内容,请使用
grep
从~/.bashrc
中过滤掉它,然后使用eval
(通常应避免使用后者,但在这种情况下它有效地提供了与 sourcing 相同的功能)。
请注意,确保环境变量PS1
有一个值是不够的,因为 Bash 在非交互式 shell 中 主动重置它 - 参见 this answer背景资料。eval "$(grep -vFx '[ -z "$PS1"] && return' ~/.bashrc)"
或者,如果您控制自己脚本的调用方式,您可以使用 bash -i script
调用它。
关于bash - 脚本中的 source .bashrc 不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43659084/