脚本中的源.bashrc无法正常工作 [英] source .bashrc in a script not working
问题描述
我正在执行一个脚本,该脚本正在安装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
顶部带有一个条件,如果发现外壳不是 non,则该条件明确停止处理-interactive .
例如,在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
无效,因为脚本在非交互式外壳中运行默认情况下.
您的选项为:
-
其中之一:停用
~/.bashrc
中的条件
-
或者:在调用
source ~/.bashrc
之前尝试模拟交互式shell .
所需的具体仿真取决于条件的具体情况,但是有两种可能的方法:如果您不提前知道会遇到什么条件,则可能必须同时雇用他们
或者,如果您控制自己的脚本的调用方式,则可以使用
bash -i script
调用它.
I am doing a script that is installing ros and after installing it, compiling a workspace with 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:
#!/bin/bash
source 01_install_ros.bash
What is important is in 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?
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.
For example, on 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:
# 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.
Your options are:
Either: deactivate the conditional in
~/.bashrc
Or: Try to to emulate an interactive shell before 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 both if 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 not enough, because Bash actively resets it in non-interactive shells - see this answer for background information.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
.
这篇关于脚本中的源.bashrc无法正常工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!