85

vagrant up如果您使用的是 Ruby 配置器,调用时传递环境变量看起来很简单:

VAR=123 vagrant up

在流浪文件中:

ENV['VAR']

我如何使用:shell配置器执行此操作?简单地这样做似乎不起作用:

$VAR
4

12 回答 12

89

从 Vagrant 1.8.0开始,您可以在这里忘记其他答案中的丑陋黑客。只需使用envshell 配置程序 ( docs ) 的选项。

在你的 Vagrantfile 中像这样使用它:

config.vm.provision "shell", path: "provisionscript.sh", env: {"MYVAR" => "value"}

这将仅为配置脚本设置环境。如果您需要为 VM 中的所有进程设置持久性环境变量,这超出了 Vagrant 配置的范围,请查看此处:vagrant 文件中的 Shell 环境变量仅在第一次传递

于 2016-06-01T08:51:31.007 回答
43

这并不理想,但我现在让它工作:

config.vm.provision "shell" do |s|
    s.inline = "VAR1 is $1 and VAR2 is $2"
    s.args   = "#{ENV['VAR1']} #{ENV['VAR2']}"
end
于 2013-10-29T01:43:30.110 回答
19

对于后代(又名,以防我再次谷歌它)......可以通过env传递键值对:

box.vm.provision :shell do |s|
  s.env = {AWS_ACCESS_KEY:ENV['AWS_ACCESS_KEY'], AWS_SECRET_KEY:ENV['AWS_SECRET_KEY']}
  s.path = 'scripts/bootstrap.sh'
end

然后在您的脚本中引用它们:

export AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY}
export AWS_SECRET_ACCESS_KEY=${AWS_SECRET_KEY}

奖励功能:

Vagrant 将处理环境变量值的引用,但键保持不变

于 2016-06-01T19:35:42.703 回答
16

我为基于 CentOS 的配置提供了这个解决方案:将所有需要的环境变量放在/etc/profile.d/vagrant.sh文件中,然后在任何配置脚本中访问它。

简而言之:

  $before_script = <<SCRIPT
  echo # vagrant profile script > /etc/profile.d/vagrant.sh
  echo export ENV_VAR1=foo.com/bar >> /etc/profile.d/vagrant.sh
  echo export ENV_VAR2=bar.com/foo >> /etc/profile.d/vagrant.sh
  chmod +x /etc/profile.d/vagrant.sh
SCRIPT

  $after_script = <<SCRIPT
    rm -rf /etc/profile.d/vagrant.sh
SCRIPT

  config.vm.provision "shell", inline: $before_script
  config.vm.provision "shell", path: "build.sh"
  config.vm.provision "shell", inline: $after_script

完整Vagrantfile的可以在这里找到 https://gist.github.com/bivas/6192d6e422f8ff87c29d

于 2014-06-11T20:35:42.537 回答
8

您可以#{ENV['VAR']}在内联脚本中使用,例如:

config.vm.provision "shell", inline: <<-END
  ...
  # Install my dotfiles are there.  If you're in a hurry you can do
  # SKIP_DOTFILES=1 vagrant up
  if ! [ -d /home/vagrant/dotfiles ] && [ -z '#{ENV['SKIP_DOTFILES']}']; then
    if ! [ -x /usr/bin/git ]; then
      DEBIAN_FRONTEND=noninteractive apt-get install -y git
    fi
    su - vagrant -c 'git clone https://github.com/mgedmin/dotfiles'
    su - vagrant -c 'dotfiles/install.sh'
  fi
  ...
  END

示例取自工作中的 Vagrantfile。

这有一些缺点:如果 $VAR 包含单引号,事情就会中断。

于 2015-05-20T13:50:45.637 回答
7

万一有人最终寻找如何在配置脚本的环境中设置变量,这对我有用。

config.vm.provision :shell, :inline => <<-SH
  export GRAPHITE_HOST=192.168.33.10
  /vagrant/install_app_with_monitoring.sh
SH

请注意,这假设您在/vagrantVM 上共享您的工作目录,但这应该是默认设置。

于 2013-11-03T21:33:40.473 回答
6

这些答案中的大多数似乎都已过时。使用 Vagrant 2.1.1 这对我有用:

  VAGRANTFILE_API_VERSION = "2" //...

  machine.vm.provision "shell", 
    env: {
      "ELASTIC_XMS" => servers["elastic"]["memory_xms"], 
      "ELASTIC_XMX" => servers["elastic"]["memory_xmx"]
    }, 
    inline: "sed -i -e \"s/-Xms.*/$ELASTIC_XMS/g\" /etc/elasticsearch/jvm.options"
于 2018-07-12T12:25:25.397 回答
2

vagrant-env插件正是这样做的。使用它,您可以将环境变量添加到.env本地目录中的文件中,该文件将加载到Vagrant文件中。我建议保留.env在你的.gitignore,这样你就可以保证你的隐私。

于 2016-03-04T22:16:18.650 回答
1

这就是我的工作方式。

我从使用 vagrant puppet provisioner 方式转变为仅使用 shell provisioner。我这样做主要是因为我不想以 root 身份运行,shell 提供程序为您提供:特权 => false。

我的旧方式:

config.vm.provision :puppet do |puppet|
  puppet.module_path = ENV.fetch('MODULES_PATH', 'modules')
  puppet.manifests_path = ENV.fetch('MANIFESTS_PATH', 'manifests')
  puppet.manifest_file  = ENV.fetch('MANIFEST_FILE', 'site.pp')
  puppet.options = "--debug"
end

我的新方式:

config.vm.provision :shell, :privileged => false do |shell|
  shell.inline = "puppet apply --debug --modulepath '/vagrant/#{ENV.fetch('MODULES_PATH', 'modules')}' --detailed-exitcodes '/vagrant/#{ENV.fetch('MANIFESTS_PATH', 'manifests')}/#{ENV.fetch('MANIFEST_FILE', 'site.pp')}'"
end
于 2015-04-21T03:30:55.787 回答
1

您可以简单地在文件中指定shell使用:inlineVagrantfile

config.vm.provision "shell", inline: %Q(/usr/bin/env FOO=1 BAR=1 bash /path/to/script.sh)

或者从 YAML 文件中加载一些额外的变量:

require 'yaml'
dir = File.dirname(File.expand_path(__FILE__))
vconfig = YAML::load_file("#{dir}/config.yml")
config.vm.provision "shell", inline: %Q(/usr/bin/env FOO=#{vconfig['foo']} bash /path/to/script.sh)

或者,您可以从命令行实现一些可选参数,例如:

# Parse optional arguments.
opts = GetoptLong.new(
  [ '--foo',  GetoptLong::OPTIONAL_ARGUMENT ], # With optional parameter.
  [ '--bar',  GetoptLong::OPTIONAL_ARGUMENT ], # With optional parameter.files.
)
opts.each do |opt, arg|
  case opt
    when '--foo'
      foo==arg
    when '--bar'
      bar=arg
  end
end

然后使用:opt['--foo'].to_s

另请参阅:如何在 Vagrant 上传递参数并将其包含在 Chef 食谱的范围内?

于 2016-03-03T16:04:04.390 回答
-2

这对我有用

VAGRANTFILE_API_VERSION = "2"

kettle_dir = ENV['KETTLE_DIR']
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
   config.vm.synced_folder kettle_dir, "/pentaho"
   config.vm.box = "ubuntu/trusty64"
end
于 2015-01-13T14:37:01.990 回答
-3

在一个 ubutnu 盒子上,我只是在 bootstrap.sh 中执行了以下操作:

echo "DBHOST=localhost" >> /etc/environment
echo "DBNAME=foo" >> /etc/environment
echo "DBUSER=root" >> /etc/environment
echo "DBPASSWD=root" >> /etc/environment
于 2016-08-02T09:02:20.963 回答