sed 脚本不在 Vagrantfile 中执行

标签 sed vagrant

我这辈子都无法使用 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/

相关文章:

curl - vagrant up 不能在 Windows 上工作

variables - 获取变量的第一个字符

bash - 在unix中用sed反转四个字母的长度

BASH:在特定 CSV 列中查找最大值

docker - zsh:找不到命令:dcos

ruby - 共享文件夹前的 Vagrant 预配置

linux - 从 csv 文件中删除标题和空行

bash - 如何在现有txt文件中添加新行

linux - 不能在 vagrant 上使用 mongoimport

macos - Vagrant 端口转发不适用于 Mavericks