bash - 脚本中的 source .bashrc 不起作用

标签 bash command-line

我正在做一个安装 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/

相关文章:

bash - 如何使用 'find'返回父目录

windows - 如何通过命令行更改现有文件夹的图标? ( Windows 10)

打印人类可读的 $PATH 输出的 Bash 命令在 OS X 上不作为 .bash_profile 中的别名工作

batch-file - "CD/D C:\"什么也没做

bash - 从日期字符串获取纪元时间

bash - 如何在已部署的 Heroku 应用程序上查看文件和文件结构

来自命令行的具有分类器快照依赖项的 Maven 发布插件

unix - 如何区分具有完整上下文的两个文件?

php - 在远程机器 php 上运行 bash 脚本

linux - 如何在 bash 末尾使用没有参数的 getopts 选项