bash 脚本中的源 .bashrc 不起作用
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/43659084/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
source .bashrc in a script not working
提问by onda47
I am doing a script that is installing ros and after installing it, compiling a workspace with catkin_make.
我正在做一个安装 ros 的脚本,在安装它之后,用 catkin_make 编译一个工作区。
I found the solution to solve my problem but I can't explain the reason. I have a file called install.bash that is calling others:
我找到了解决我的问题的解决方案,但我无法解释原因。我有一个名为 install.bash 的文件正在调用其他文件:
#!/bin/bash
source 01_install_ros.bash
What is important is in 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 ""
As written in comments, sourcing .bashrc instead of directly setup.bash doesn't work. I really don't get why. Can you explain me?
正如评论中所写,采购 .bashrc 而不是直接 setup.bash 是行不通的。我真的不明白为什么。你能解释一下吗?
回答by mklement0
Some platforms come with a ~/.bashrc
that has a conditional at the top that explicitly stops processing if the shell is found to be non-interactive.
某些平台带有~/.bashrc
在顶部有条件的 ,如果发现 shell是非交互式的,则明确停止处理。
For example, on Ubuntu 18.04:
例如,在 Ubuntu 18.04 上:
# If not running interactively, don't do anything
case $- in
*i*) ;;
*) return;;
esac
A similar test, seen in /etc/bash.bashrc
on the same platform:
/etc/bash.bashrc
在同一平台上看到的类似测试:
# If not running interactively, don't do anything
[ -z "$PS1" ] && return
If this is the case, sourcing ~/.bashrc
from a scriptwill have no effect,because scripts run in non-interactiveshells by default.
如果是这种情况,从脚本中获取资源将不起作用,~/.bashrc
因为脚本默认在非交互式shell 中运行。
Your optionsare:
您的选择是:
Either: deactivate the conditionalin
~/.bashrc
Or: Try to to emulate an interactive shellbefore invoking
source ~/.bashrc
.
The specific emulation needed depends on the specifics of the conditional, but there are two likely approaches; you may have to employ them bothif you don't know ahead of time which conditional you'll encounter:set -i
temporarily to make$-
containi
, indicating an interactive shell.- If you know the contents of the line that performs the interactivity test, filter it out of the
~/.bashrc
usinggrep
, and then source the result witheval
(the latter should generally be avoided, but it in this case effectively provides the same functionality as sourcing).
Note that making sure that environment variablePS1
has a value is notenough, because Bash actively resets itin non-interactive shells - see this answerfor background information.eval "$(grep -vFx '[ -z "$PS1" ] && return' ~/.bashrc)"
或者:停用有条件的
~/.bashrc
或者:尝试以模拟一个交互的shell调用之前
source ~/.bashrc
。
所需的特定模拟取决于条件的具体情况,但有两种可能的方法;您可能需要使用它们两个,如果你不提前知道时间,这条件你会遇到:set -i
暂时使$-
包含i
,表示交互式外壳。- 如果您知道执行交互性测试的行的内容,请将其从
~/.bashrc
using 中过滤掉grep
,然后使用获取结果eval
(通常应避免使用后者,但在这种情况下,它有效地提供了与 sourcing 相同的功能)。
需要注意的是确保环境变量PS1
有一个值是不足够的,因为猛砸积极重置它在非交互shell -看到这个答案的背景信息。eval "$(grep -vFx '[ -z "$PS1" ] && return' ~/.bashrc)"
Alternatively, if you control how your own script is invoked, you can invoke it with bash -i script
.
或者,如果您控制如何调用自己的脚本,则可以使用bash -i script
.