Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I escape a Ruby string containing newlines (and possibly other special characters) to a valid shell variable value?

I need to write a Ruby function which generates a correct Bash export statement given a variable name and the value it should be assigned to. My current attempt is

def export(variable, string)
  "export #{variable}=#{Shellwords.escape(string)}"
end

However, it doesn't behave quite as I expect. E.g.

[2] pry(main)> export("X", "a\nb")
"export X=a'\n'b"

and then

export X=a'\n'b
echo "$X"

in the shell gives

a\nb

instead of the desired

a
b

If it matters (I don't expect it to, but just in case) the statement will be written into a file which will be sourced later.

like image 349
Alexey Romanov Avatar asked Sep 12 '25 23:09

Alexey Romanov


1 Answers

You're copy-pasting the auto-echoed string from irb, not the value of said string. The auto-echoing is showing you a Ruby string literal with Ruby escapes left in, so you get:

irb(main)> Shellwords.shellescape("a\nb")
=> "a'\n'b"

If you printed that string (e.g. with puts) to get its raw value (with the escapes printed as their real characters), e.g.

irb(main)> puts Shellwords.shellescape("a\nb")
a'
'b
=> nil

and copy-pasted that to make:

export X=a'
'b
echo "$X"

it would work just fine.

Similarly, writing "export X=#{Shellwords.escape(string)}" to a file (via puts or other actual I/O APIs that write the string's value, not its representation) for later use would work just fine, because that would be inserting the string's value, and the file would end up with a raw newline between the single-quotes, not \n.

like image 153
ShadowRanger Avatar answered Sep 15 '25 12:09

ShadowRanger