【问题标题】:source .bashrc in a script not working脚本中的源 .bashrc 不起作用
【发布时间】:2017-04-27 13:19:44
【问题描述】:

我正在编写一个正在安装 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 ""

正如在 cmets 中所写的那样,采购 .bashrc 而不是直接 setup.bash 是行不通的。我真的不明白为什么。你能解释一下吗?

【问题讨论】:

  • .bashrc 旨在由 Bash 本身读取。为什么您认为可能有必要在脚本中执行此操作?
  • 因为我在01_install_ros.bash 的末尾添加了一行,即从 ros 采购 setup.bash。我需要采购它。
  • 因为我添加了行source /opt/ros/kinetic/setup.bash" at the end of .bashrc. I do that in 01_install_ros.bash`。我需要获取这个 setup.bash 才能访问 $PATH 中的 catkin_make。我不明白为什么我在采购 .bashrc 时没有这种访问权限。我希望清楚。
  • 使用exec bash启动一个新的Bash,它已经读取了更新的.bashrc
  • 我认为你不明白。我不寻找解决方案。我想要一个解释。为什么它不适用于source ~/.bashrc?我知道怎么解决:直接source /opt/ros/kinetic/setup.bash

标签: bash command-line


【解决方案1】:

一些平台带有~/.bashrc,它在顶部有一个条件,如果发现外壳是非交互的,它会显式停止处理 - 即使@无论如何,987654323@ 只会在交互式(非登录)会话中自动获取~/.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 获取结果(通常应避免使用后者,但它在这种情况下有效地提供了与采购相同的功能)。
      请注意,确保环境变量 PS1 有一个值是不够,因为 Bash 在非交互式 shell 中主动重置它 - 有关背景信息,请参阅 this answer
      • eval "$(grep -vFx '[ -z "$PS1" ] && return' ~/.bashrc)"

或者,如果您控制如何调用自己的脚本,您可以使用
bash -i script 调用它。

【讨论】:

  • set -i 似乎不起作用,我也无法手动修改$-
  • 停用条件有什么缺点吗?
  • @deanresin:我不这么认为,因为无论如何bash 只会在交互式(非登录)会话中自动获取~/.bashrc
  • @nupanick,答案表明set -i 仅在~/.bashrc 包含答案中首先列出的条件时才有效,其中检查了(只读)$_ 变量。如果条件基于$PS1 或类似的,则必须使用基于grep 的技术。
猜你喜欢
  • 2018-06-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多