Chef/Bash 食谱中 String.Format 的等价物

Equivalent of String.Format in a Chef/Bash Recipe

在厨师食谱中寻找类似于 .Net 字符串格式的内容,即

string phone = String.format("phone: {0}",_phone);

我有一个 Chef 食谱,我需要用这些参数中的 30 个来构建一个命令字符串,所以希望有一个简洁的方法来构建该字符串,原则上我就是这样做的

a=node['some_var'].to_s
ruby_block "run command" do
  block do
    cmd = shell_out!("node mycommand.js #{a}; exit 2;")           
  end
end

当我尝试此操作时出现错误

path.join 的参数必须是字符串 感谢任何提示

Chef 运行分两个阶段:

编译并执行(有关详细信息,请参阅 https://www.chef.io/blog/2013/09/04/demystifying-common-idioms-in-chef-recipes/)。

您对 a 的变量赋值发生在编译时,例如当厨师加载所有食谱时。 ruby 块将在收敛时以执行模式执行,不能访问变量 a.

所以最简单的解决方案可能是将属性放入 ruby 块中:

   ruby_block "run command with argument #{node['some_var']}" do
     block do
       shell_out!("node mycommand.js #{node['some_var']}")
     end
   end

然而:

  1. 如果您不需要执行 Ruby 代码,请考虑使用 executebash 资源。

  2. 请记住,如果要围绕它构建某种循环,则必须具有唯一的资源名称。一个简单的方法是在名称中添加一些独特的东西 ruby_block "something unique per loop iteration" do ... end

  3. 我真的不明白你的退出代码2。这是一个错误代码。它会让厨师每次都抛出异常。 (如果退出代码 != 0,shell_out! 抛出异常,请参阅 https://github.com/chef/chef/blob/master/lib/chef/mixin/shell_out.rb#L24-L28

  4. 资源将在每个厨师 运行 上执行。这可能不符合您的兴趣。考虑加一个守卫(test),防止不必要的执行,见https://docs.chef.io/resource_common.html#guards