在 Vagrant 配置期间更新 .bashrc 和环境变量
Updating .bashrc and environment variables during Vagrant provisioning
我正在使用 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 会 运行?
更新: 进一步尝试...似乎 source /home/vagrant/.bashrc
对我的 shell 脚本没有影响 - 我可以把 echo "hello"
在 .bashrc
文件中,并且在配置期间不输出(但如果我 运行 source /home/vagrant/.bashrc
在登录时输出。
我也在 shell 脚本中尝试了 su -c "source /home/vagrant/.bashrc" vagrant
,但没有什么不同。
更新 2: 删除了 $BASHRC_PATH
变量,这使问题变得混乱。
更新 3: 在 中,我得到了为什么 source /home/vagrant/.bashrc
不起作用的答案:[=13= 的第一部分] 文件阻止它在 运行 "not interactively" 时以这种方式做任何事情。
我找到了一个解决方案,但我不知道它是否是最好的。感觉有点不对劲,因为它在重复一些事情,但是...
我仍然将这些行附加到 .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
。)
Vagrant 脚本供应器将 运行 作为 root,因此它的主目录 (~) 将是 /root。在您的脚本中,如果您定义 BASHRC_PATH=/home/vagrant,那么我相信您的步骤会起作用:附加到 /home/vagrant/.bashrc.[=12=,然后从中获取]
更新:
打破我早先的想法^^因为BASHRC_PATH已经设置正确。
作为替代方案,我们可以使用 .profile 或 .bash_profile。这是一个设置环境变量 FOO 的简化示例,使其在配置期间和 ssh 登录后可用:
Vagrantfile
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
Ubuntu 框中的 .bashrc 不起作用。您必须创建 .bash_profile 并添加:
if [ -f ~/.bashrc ]; then
. ~/.bashrc
fi
如前所述 ,Vagrant 在配置期间禁止交互式 shells - 显然,仅适用于某些盒子(尽管需要参考)。对我来说,这会影响官方 Ubuntu Trusty 和 Xenial 盒子。
但是,您可以使用 sudo -H -u USER_HERE bash -i -c 'YOUR COMMAND HERE'
模拟交互式 bash shell
答案取自:
这对我在配置 Ubuntu/trusty64 和 xenial64 机器时通过 rbenv 安装 Ruby 和通过 nvm 安装 Node 很有效。
我正在使用 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 会 运行?
更新: 进一步尝试...似乎 source /home/vagrant/.bashrc
对我的 shell 脚本没有影响 - 我可以把 echo "hello"
在 .bashrc
文件中,并且在配置期间不输出(但如果我 运行 source /home/vagrant/.bashrc
在登录时输出。
我也在 shell 脚本中尝试了 su -c "source /home/vagrant/.bashrc" vagrant
,但没有什么不同。
更新 2: 删除了 $BASHRC_PATH
变量,这使问题变得混乱。
更新 3: 在 source /home/vagrant/.bashrc
不起作用的答案:[=13= 的第一部分] 文件阻止它在 运行 "not interactively" 时以这种方式做任何事情。
我找到了一个解决方案,但我不知道它是否是最好的。感觉有点不对劲,因为它在重复一些事情,但是...
我仍然将这些行附加到 .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
。)
Vagrant 脚本供应器将 运行 作为 root,因此它的主目录 (~) 将是 /root。在您的脚本中,如果您定义 BASHRC_PATH=/home/vagrant,那么我相信您的步骤会起作用:附加到 /home/vagrant/.bashrc.[=12=,然后从中获取]
更新:
打破我早先的想法^^因为BASHRC_PATH已经设置正确。
作为替代方案,我们可以使用 .profile 或 .bash_profile。这是一个设置环境变量 FOO 的简化示例,使其在配置期间和 ssh 登录后可用:
Vagrantfile
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
Ubuntu 框中的 .bashrc 不起作用。您必须创建 .bash_profile 并添加:
if [ -f ~/.bashrc ]; then
. ~/.bashrc
fi
如前所述
但是,您可以使用 sudo -H -u USER_HERE bash -i -c 'YOUR COMMAND HERE'
答案取自:
这对我在配置 Ubuntu/trusty64 和 xenial64 机器时通过 rbenv 安装 Ruby 和通过 nvm 安装 Node 很有效。