简体   繁体   English

脚本中的 source.bashrc 不起作用

[英]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。
    • If you know the contents of the line that performs the interactivity test, filter it out of the ~/.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获取结果(通常应避免使用后者,但在这种情况下它有效地提供了相同的结果采购功能)。
      Note that making sure that environment variable 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM