Passing variable to a shell script provisioner in vagrant
You're correct. The way to pass arguments is with the :args
parameter.
config.vm.provision :shell, :path => "bootstrap.sh", :args => "'first arg' second"
Note that the single quotes around first arg
are only needed if you want to include spaces as part of the argument passed. That is, the code above is equivalent to typing the following in the terminal:
$ bootstrap.sh 'first arg' second
Where within the script $1 refers to the string "first arg" and $2 refers to the string "second".
The v2 docs on this can be found here: http://docs.vagrantup.com/v2/provisioning/shell.html
Pass command line argument to vagrant shell script provisioner
This is what I would try - I guess there are possibilities as Vagrantfile is a ruby script, you can use most of ruby possibilities
Be careful though as vagrant might need to check for variables, for example when doing vagrant up arg1 arg2
, it expects arg1 and arg2 to be machine names defined in Vagrantfile and will raise an error as it cannot find it
So you would need to pass those variables like
vagrant --arg1 --arg2 up
To read them you could
# -*- mode: ruby -*-
# vi: set ft=ruby :
v1 = ARGV[0]
v2 = ARGV[1]
array_arg = [v1, v2]
Vagrant.configure("2") do |config|
blabla config
array_arg.each do |arg|
config.vm.provision "shell", run: "always" do |s|
s.inline = "echo $1"
s.args = arg
end
end
end
for example, the execution would give
fhenri@machine:~/project$ vagrant --arg1 --arg2 up
. . . . .
==> default: Running provisioner: shell...
default: Running: inline script
==> default: stdin: is not a tty
==> default: --arg1
==> default: Running provisioner: shell...
default: Running: inline script
==> default: stdin: is not a tty
==> default: --arg2
Evaluate expression on host machine and pass results to the provisioning shell script as an argument
You were almost there but vagrant runs an SSH command with all parameters so your arguments are resolved within the guest VM. What you need to do is to save your username value from the host before making the shell provisioning passing as parameter this value.
Here is an example to be added in your Vagrantfile
username = `whoami`.chomp # you need chomp as the result of the command executed this way returns \n at the end
config.vm.provision "shell", privileged: false, path: "provisioning/config-git.sh", args: "#{username}"
The output of my local execution
fhenri@machine:~/project/examples/vagrant/ubuntu$ whoami
fhenri
fhenri@machine:~/project/examples/vagrant/ubuntu$ vagrant ssh
Welcome to Ubuntu 12.04.1 LTS (GNU/Linux 3.2.0-29-virtual x86_64)
* Documentation: https://help.ubuntu.com/
Last login: Wed Dec 16 22:59:01 2015 from 172.16.42.1
vagrant@ubuntu:~$ whoami
vagrant
vagrant@ubuntu:~$ git config --list
user.email=fhenri@stackoverflow.com
user.name=fhenri
How to pass parameter on 'vagrant up' and have it in the scope of Vagrantfile?
You cannot pass any parameter to vagrant. The only way is to use environment variables
MY_VAR='my value' vagrant up
And use ENV['MY_VAR']
in recipe.
Pass environment variables to vagrant shell provisioner
It's not ideal, but I got this to work for now:
config.vm.provision "shell" do |s|
s.inline = "VAR1 is $1 and VAR2 is $2"
s.args = "#{ENV['VAR1']} #{ENV['VAR2']}"
end
Vagrant passing args from command line into provisioned file
The most common way to do this kind of thing is to use environment variables. For example:
ACCOUNT=iwayneo vagrant provision
Then you can use it in Vagrantfile using the ENV class. Assuming you want to pass it as an argument to a shell provisioner script, you can use something like this:
if !ENV.has_key?("ACCOUNT")
raise "Please specify the `ACCOUNT` environment variable"
end
Vagrant.configure("2") do |config|
config.vm.provision "shell", path: "script.sh", args: ENV["ACCOUNT"]
end
EDIT: Addition for the sh script setup:
You have to source
your sh script for the variables to take effect in the shell session. Otherwise they are only available during the script run for that subshell. Similarly, you also need to export
the variables in .bashrc for them to be available in the Vagrant process.
All this is related to how shells and child processes work with environment variables. Nothing special with Vagrant.
Passing the host's current user to to vagrant shell provisioner
That's because your inline shell script runs inside the vagrant box.
You can do it like this:
Get username from host depending on platform (you can simplify this if you never expect a windows host).
@host_user = Gem.win_platform? ? "#{ENV['USERNAME']}" : "#{ENV['USER']}"
Pass the username from the host as environment variable during the provisioning and use it in an inline script.
config.vm.provision "Passing host username as env var...", type: :shell, inline: $hostUser, env: {"HOST_USER" => "#{@host_user}"}
Add this outside the ruby part, it gets then run by the code above and appends the username which got passed as environment variable to the file you specified:
$hostUser = <<-SET_HOST_USER
echo "$HOST_USER" > /etc/profile.d/me"
SET_HOST_USER
Passing ruby variable to provisioner
Use #{variable}
to use string expansion in Ruby:
config.vm.provision :shell, :path => "set_rmi_hostname.sh", :args => "#{ip_address} #{target}"
Vagrant: passing parameters in windows
So I stumbled on this issue as well. To pass parameters from command prompt to Vagrantfile it should pass as an environment variable, and you can do it in one line:
set "SERV=client" && vagrant up
In the Vagrantfile, you then can access the parameter as ENV['SERV']
A heads-up is that the environment variable will still exist in the environment after vagrant has finished.
Related Topics
Problem Running Thinking Sphinx with Rails 2.3.5
Get Pry to Display Characters Like [äöüßÄÖÜß] (Utf-8 Encoding)? (Possibly Windows-Specific Issue)
Rails - Multi Tenant Application with Customization Framework
How to Define a Simple Global Variable in an Rspec Test That Can Be Accesed by Helper Functions
How to Install Rmagick Gem on Windows
Ruby: Overriding the Puts Method
Remove a Tag But Keep the Text
Vagrant Ssh Not Working in Mobaxterm on Windows
Exec the Cd Command in a Ruby Script
How to Use H2 as Embedded Database in Postgres-Compat Mode, from Jruby/Rails
Validate That String Contains Only Allowed Characters in Ruby
No Such File to Load -- Bundler/Setup (Ruby on Rails)
Rake Test Very Slow in Windows
What Could Be Causing This Rails Ioerror Closed Stream
What Regex How to Use to Get the Domain Name from a Url in Ruby