如何将包含换行符(可能还有其他特殊字符)的 Ruby 字符串转义为有效的 shell 变量值?

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

提问人:Alexey Romanov 提问时间:6/27/2023 最后编辑:ShadowRangerAlexey Romanov 更新时间:6/28/2023 访问量:55

问:

我需要编写一个 Ruby 函数,该函数在给定变量名称和应分配给的值的情况下生成正确的 Bash 导出语句。我目前的尝试是

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

但是,它的行为并不像我预期的那样。例如

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

然后

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

在外壳中给出

a\nb

而不是想要的

a
b

如果它很重要(我不希望它,但以防万一),该语句将被写入一个文件,该文件将在以后提供。

Ruby 字符串 bash 转义

评论

0赞 jordanm 6/27/2023
你需要的不仅仅是逃避:.在这里看我的答案:unix.stackexchange.com/a/48121/13796X=$'a\nb'
0赞 Alexey Romanov 6/27/2023
@jordanm 这很有帮助,但我的问题是如何为任意的 Ruby 字符串获取它,而不是这个特定的字符串。

答:

4赞 ShadowRanger 6/27/2023 #1

您正在复制粘贴自动回显的字符串,而不是所述字符串的值。自动回显向你显示一个 Ruby 字符串文字,其中保留了 Ruby 转义,所以你会得到:irb

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

如果您打印该字符串(例如,使用 )以获取其原始值(将转义打印为实数),例如puts

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

并复制粘贴以使其:

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

它会很好用。

同样,写入文件(通过或其他实际的 I/O API 写入字符串的值,而不是其表示形式)以供以后使用也可以正常工作,因为这将插入字符串的值,并且文件最终会在单引号之间使用原始换行符,而不是 ."export X=#{Shellwords.escape(string)}"puts\n

评论

1赞 Alexey Romanov 6/27/2023
当然,这是有道理的。谢谢!
0赞 Alexey Romanov 6/27/2023
写入文件实际上是我尝试过的,但后来开始担心它不起作用:)export X=#{Shellwords.escape(string)}
2赞 ShadowRanger 6/27/2023
@AlexeyRomanov:当你怀疑自己无法找到正确的解决方案时,总是很痛苦。:-)