-1

I need to form a user-data script from Ruby so I need all escaping characters to remain. When I do this:

  def user_data
     "#!/bin/bash
     sed -i -e '/<Name>loadbalanceServerIP<\/Name>/,/<Value>/s/<Value>[^<]*/<Value>1.1.1.1/' /home/wowza/conf/Server.xml"
  end

The string removes the \ in the Name tag. If I put two \, it keeps them both. Any suggestion as how to keep the string the same way I wrote it?

Thank you!

Leticia Esperon
  • 2,499
  • 1
  • 18
  • 40
  • It's correct ruby behaviour. When you puts your string with double \, you will see only one. – Dmitry Z. Nov 16 '16 at 15:33
  • 1
    what's "scaping characters"? – Sergio Tulentsev Nov 16 '16 at 15:38
  • @SergioTulentsev I think you should read this as escaping – Dmitry Z. Nov 16 '16 at 15:42
  • If I use two \\ it keeps them both. :( – Leticia Esperon Nov 16 '16 at 15:47
  • 1
    @LeticiaEsperon no, it doesn't. It _shows_ two backslashes when you are inspecting the string, but the string contains only one backslash: `"\\".size #=> 1` – Stefan Nov 16 '16 at 15:50
  • Oh!! That's right. Thank you very much, that was the information I was lacking. – Leticia Esperon Nov 16 '16 at 16:02
  • I'd recommend reading http://stackoverflow.com/q/8554479/128421 and https://en.wikipedia.org/wiki/Escape_character. This is well documented behavior. – the Tin Man Nov 16 '16 at 16:09
  • I am not able to reproduce your problem: `"\\".length #=> 1`. Which version of Ruby are you using? Which implementation? How *exactly* are you constructing your `String`? Is it a literal? Does it come from somewhere else? Do you parse it? Generate it? Could there be a double parsing or double escaping bug somewhere in your code? – Jörg W Mittag Nov 16 '16 at 16:12
  • This question is different. The OP wants to enter / keep a multi-line string containing `'` and ``\`` (literally) as-is, without having to specifically quote anything. – Stefan Nov 16 '16 at 16:14

2 Answers2

1

You can use the %q delimiter rather than ":

def user_data
     %q[#!/bin/bash
     sed -i -e '/<Name>loadbalanceServerIP<\/Name>/,/<Value>/s/<Value>[^<]*/<Value>1.1.1.1/' /home/wowza/conf/Server.xml]
end
ReggieB
  • 8,100
  • 3
  • 38
  • 46
0

I'd use a heredoc:

def user_data
  <<~'SH'
    #!/bin/bash
    sed -i -e '/<Name>loadbalanceServerIP<\/Name>/,/<Value>/s/<Value>[^<]*/<Value>1.1.1.1/' /home/wowza/conf/Server.xml
  SH
end

puts user_data

~ removes the indentation, and the single quotes around SH disable interpolation and escaping.

Output:

#!/bin/bash
sed -i -e '/<Name>loadbalanceServerIP<\/Name>/,/<Value>/s/<Value>[^<]*/<Value>1.1.1.1/' /home/wowza/conf/Server.xml
Stefan
  • 109,145
  • 14
  • 143
  • 218