【问题标题】:Updating .bashrc and environment variables during Vagrant provisioning在 Vagrant 配置期间更新 .bashrc 和环境变量
【发布时间】:2015-06-16 15:40:30
【问题描述】:

我正在使用 Vagrant 设置一个带有 python、pip、virtualenv、virtualenvwrapper 和一些要求的盒子。配置 shell 脚本将 the required lines for virtualenvwrapper 添加到 .bashrc。它会进行非常基本的检查,以确保它们不存在,因此它不会在每个规定中重复它们:

if ! grep -Fq "WORKON_HOME" /home/vagrant/.bashrc; then
    echo 'export WORKON_HOME=/home/vagrant/.virtualenvs' >> /home/vagrant/.bashrc
    echo 'export PROJECT_HOME=/home/vagrant/Devel' >> /home/vagrant/.bashrc
    echo 'source /usr/local/bin/virtualenvwrapper.sh' >> /home/vagrant/.bashrc

    source /home/vagrant/.bashrc
fi

似乎工作正常;配置完成后,这些行在.bashrc,我可以 ssh 到盒子并使用 virtualenvwrapper。

但是,virtualenvwrapper 在配置期间不起作用。在上面的部分之后,接下来会检查 pip 要求文件并尝试使用 virtualenvwrapper 进行安装:

if [[ -f /vagrant/requirements.txt ]]; then
    mkvirtualenv 'myvirtualenv' -r /vagrant/requirements.txt
fi

但这会产生:

==> default: /tmp/vagrant-shell: line 50: mkvirtualenv: command not found

如果我尝试从该 shell 脚本中回显 $WORKON_HOME,则不会出现任何内容。

我缺少什么让这些环境变量可用,所以 virtualenvwrapper 会运行?

更新: 进一步尝试...似乎在我的 shell 脚本中执行 source /home/vagrant/.bashrc 没有效果 - 我可以将 echo "hello" 放入 .bashrc 文件中,但事实并非如此配置期间的输出(但如果我在登录时运行source /home/vagrant/.bashrc

我也在 shell 脚本中尝试过su -c "source /home/vagrant/.bashrc" vagrant,但没有什么不同。

更新 2:删除了 $BASHRC_PATH 变量,这使问题变得混乱。

更新 3:another question 我得到了关于为什么 source /home/vagrant/.bashrc 不起作用的答案:.bashrc 文件的第一部分阻止它在运行“不以这种方式交互”。

【问题讨论】:

  • 我不知道为什么这被否决了……我做错了什么?

标签: python shell vagrant virtualenvwrapper


【解决方案1】:

Vagrant 脚本配置器将以 root 身份运行,因此它的主目录 (~) 将是 /root。如果您在脚本中定义 BASHRC_PATH=/home/vagrant,那么我相信您的步骤会起作用:附加到 /home/vagrant/.bashrc,然后从 /home/vagrant/.bashrc 获取。

更新:

放弃我之前的想法 ^^ 因为 BASHRC_PATH 已经设置正确。

作为替代方案,我们可以使用 .profile 或 .bash_profile。这是一个设置环境变量 FOO 的简化示例,使其在配置期间和 ssh 登录后可用:

流浪文件

Vagrant.configure(2) do |config|
  config.vm.box = "hashicorp/precise32"

  $prov_script = <<SCRIPT
if ! grep -q "export FOO" /home/vagrant/.profile; then
  sudo echo "export FOO=bar" >> /home/vagrant/.profile
  echo "before source, FOO=$FOO"
  source /home/vagrant/.profile
  echo "after source, FOO=$FOO"
fi
SCRIPT

  config.vm.provision "shell", inline: $prov_script
end

结果

$ vagrant up
...
==> default: Running provisioner: shell...
    default: Running: inline script
==> default: before source, FOO=
==> default: after source, FOO=bar
$ vagrant ssh -c 'echo $FOO'
bar
$ vagrant ssh -c 'tail -n 1 ~/.profile'
export FOO=bar

【讨论】:

  • 我应该说我将BASHRC_PATH 设置为...它已经设置为/home/vagrant,所以不是这样,但谢谢!
  • 我现在已经添加了,所以这个问题更有意义。
  • 现在我已经完全删除了它,因为它会分散人们对问题的注意力!
  • @PhilGyford 我使用 .profile 用另一种方法更新了我的答案,避免了 .bashrc 是否准备就绪的问题。
【解决方案2】:

我找到了一个解决方案,但我不知道它是否是最好的。重复的时候感觉有点不对劲,但是……

我仍然将这些行附加到.bashrc,因此如果我 ssh 进入机器,virtualenvwrapper 将工作。但是,因为source /home/vagrant/.bashrc在脚本运行过程中似乎没有任何作用,所以我不得不明确地重复这三个命令:

if ! grep -Fq "WORKON_HOME" $BASHRC_PATH; then
    echo 'export WORKON_HOME=$HOME/.virtualenvs' >> $BASHRC_PATH
    echo 'export PROJECT_HOME=$HOME/Devel' >> $BASHRC_PATH
    echo 'source /usr/local/bin/virtualenvwrapper.sh' >> $BASHRC_PATH
fi

WORKON_HOME=/home/vagrant/.virtualenvs
PROJECT_HOME=/home/vagrant/Devel
source /usr/local/bin/virtualenvwrapper.sh

(顺便说一句,我还意识到在 vagrant 配置期间$HOME/root,而不是我假设的/home/vagrant。)

【讨论】:

    【解决方案3】:

    Ubuntu 框中的 .bashrc 不起作用。您必须创建 .bash_profile 并添加:

    if [ -f ~/.bashrc ]; then
      . ~/.bashrc
    fi
    

    【讨论】:

      【解决方案4】:

      正如in your other Q 所提到的,Vagrant 在配置期间禁止交互式外壳 - 显然,仅适用于某些盒子(尽管需要参考)。对我来说,这会影响官方的 Ubuntu Trusty 和 Xenial 盒子。

      但是,您可以使用 sudo -H -u USER_HERE bash -i -c 'YOUR COMMAND HERE' 模拟交互式 bash shell

      答案来自:https://stackoverflow.com/a/30106828/4186199

      在配置 Ubuntu/trusty64 和 xenial64 框时,这对我通过 rbenv 安装 Ruby 和通过 nvm 安装 Node 很有用。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-08-29
        • 2015-08-28
        • 2014-09-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-11-08
        相关资源
        最近更新 更多