chef-infrachef-recipechef-solocookbook

How to pass attribute value with double slash to a template


I am trying to develop a cookbook which is going to support both Windows and Linux platform. I am having some issue while working with a template. So, basically I am trying to put a shell script which will have a export command with a path. But I am not able to get the exact value on the shell script on the windows.

Attribute:

root_path = value_for_platform(
  'windows' => { 'default' => "D:\\" },
  'default' => '/opt'
)
xyz_path = value_for_platform(
  'windows' => { 'default' => "#{root_path}xyz_app\\tool\\bin\\xyz.bat" },
  'default' => "#{root_path}/xyz_app//tool//bin//xyz"
)

Recipe:

template File.join(root_path, '/tmp/xyz_path.sh') do
  source 'xyz_path.sh.erb'
  mode '0755'
  variables({
    :xyz_path => xyz_path
  })
end

Template

#!/bin/bash

export xyz_path = <%= @xyz_path %>

Expectation on Windows

#!/bin/bash

export xyz_path = D:\\xyz_app\\tool\\bin\\xyz.bat

Reality on Windows

#!/bin/bash

export xyz_path = D:\xyz_app\tool\bin\xyz.bat

Solution

  • Use 4 backslashes to get what you desire .

    root_path = value_for_platform(
      'windows' => { 'default' => "D:\\\\" },
      'default' => '/opt'
    )
    xyz_path = value_for_platform(
      'windows' => { 'default' => "#{root_path}xyz_app\\\\tool\\\\bin\\\\xyz.bat" },
      'default' => "#{root_path}/xyz_app//tool//bin//xyz"
    )
    

    Since the backslash is the escape character the first backslash escapes the second one so you need to repeat this twice in order to get two backslashes in the output