我这辈子都无法使用 sed 来处理 vagrant provisioning。我想对/etc/hosts 进行内联更改。
我已验证 sed 命令在 shell 中运行时有效。
这是我的 Vagrantfile:
# vi: set ft=ruby :
########### Global Config ###########
machines = ["admin2"]
num_hdd_per_osd = 3
vagrant_box = %q{bento/ubuntu-18.04}
#####################################
machines.each do |machine|
Vagrant.configure("2") do |config|
config.vm.define machine do |node| #name vagrant uses to reference this VM
node.vm.box = vagrant_box
node.vm.hostname = machine
node.vm.network "private_network", ip: "192.168.0.#{ machines.index(machine) + 10}"
node.vm.provider "virtualbox" do |vb|
# Display the VirtualBox GUI when booting the machine
vb.gui = false
vb.name = machine # name virtualbox uses to refer to this vm
# Customize the amount of memory on the VM:
vb.memory = "1048"
# Core Count
vb.cpus = "2"
end
if node.vm.hostname.include? "admin"
node.vm.provision "shell", inline: <<-SHELL
sed -i.bak -e 's,\\(127\\.0\\.0\\.1[[:space:]]*localhost\\),\\1aa,' /etc/hosts
SHELL
end
end
end
end
我应该看到/etc/hosts 更改为 127.0.0.1 localhostaa
但它没有变化。
怎么了?
编辑:我根据下面 Alex 的建议更新了代码。它现在使用 inline: <<-SHELL 并转义所有转义符(所以双重转义)。有用!
最佳答案
问题是你的 Vagrantfile 是 Ruby 代码,而你的 sed 脚本在 Ruby here 字符串中。
如果您尝试这个简化的 Ruby 脚本:
# test.rb
puts <<-SHELL
sudo sed -i.bak -e 's,\(127\.0\.0\.1[[:space:]]*localhost\),\1aa,' /etc/host
SHELL
您可能会看到问题:
▶ ruby test.rb
sudo sed -i.bak -e 's,(127.0.0.1[[:space:]]*localhost),aa,' /etc/host
也就是\1
及其他\
在插入此处字符串之前由 Ruby 解释。
最好的选择是使用 <<'SHELL'
符号,类似于您在 Bash 中所做的:
node.vm.provision "shell", inline: <<-'SHELL'
sed -i.bak -e 's,\(127\.0\.0\.1[[:space:]]*localhost\),\1aa,' /etc/hosts
SHELL
另一种选择是转义 \1
中的反斜杠.另外,请注意,据我所知,对 sudo
的调用那里也不需要。
但是,如果您需要在此脚本中插入一个字符串,您可以这样做:
# test.rb
mystring = 'aa'
$script = "sed -i.bak -e '" +
's,\(127\.0\.0\.1[[:space:]]*localhost\),\1' + "#{mystring},' /etc/hosts"
然后在你的配置器中:
node.vm.provision "shell", inline: $script
另见 this相关回答。
关于sed 脚本不在 Vagrantfile 中执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56103974/