Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

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

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

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.

>Solution :

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.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading