[英]source .bashrc in a script not working
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.正如评论中所写, sourcing.bashrc 而不是直接 setup.bash 不起作用。 I really don't get why.
我真的不明白为什么。 Can you explain me?
你能解释一下吗?
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 - even though bash
only automatically sources ~/.bashrc
in interactive (non-login) sessions anyway.一些平台带有一个
~/.bashrc
,它在顶部有一个条件,如果发现 shell是非交互式的,它会明确停止处理——尽管bash
无论如何只会在交互式(非登录)会话中自动获取~/.bashrc
.
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 script will have no effect, because scripts run in non-interactive shells by default.如果是这种情况,从脚本中获取
~/.bashrc
将不起作用,因为默认情况下脚本在非交互式shell 中运行。
Your options are:您的选择是:
Either: deactivate the conditional in ~/.bashrc
要么:停用
~/.bashrc
中的条件
Or: Try to to emulate an interactive shell before invoking source ~/.bashrc
.或者:在调用
source ~/.bashrc
之前尝试模拟交互式 shell 。
The specific emulation needed depends on the specifics of the conditional, but there are two likely approaches;所需的具体仿真取决于条件的具体情况,但有两种可能的方法; you may have to employ them both if you don't know ahead of time which conditional you'll encounter:
如果您事先不知道会遇到哪个条件,则可能必须同时使用它们:
set -i
temporarily to make $-
contain i
, indicating an interactive shell.set -i
使$-
包含i
,表示交互式 shell。~/.bashrc
using grep
, and then source the result with eval
(the latter should generally be avoided, but it in this case effectively provides the same functionality as sourcing).grep
将其从~/.bashrc
中过滤掉,然后使用eval
获取结果(通常应避免使用后者,但在这种情况下它有效地提供了相同的结果采购功能)。PS1
has a value is not enough, because Bash actively resets it in non-interactive shells - see this answer for background information.PS1
具有值是不够的,因为 Bash 在非交互式 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
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.