如何"收缩"字符串以逃避Bash中的特殊字符?

Jam*_*igh 2 string bash escaping

有很多方法可以扩展转义字符串,但是如何使用shell命令将字符串作为参数并将其转义?

以下是不同扩展方式的一些示例:

$ echo -e '\x27\\012\b34\n56\\\aa7\t8\r 9\0\0134\047'
'\0134
 9\'7   8
$ echo $'\x27\\012\b34\n56\\\aa7\t8\r 9\0\0134\047'
'\0134
 9\a7   8
$ PS1='(5)$ '  # At least tab-width - 3 long; 5 columns given typical tab-width.
(5)$ printf %b '\x27\\012\b34\n56\\\aa7\t8\r 9\0\0134\047'
'\0134
 9\'(5)$ 
Run Code Online (Sandbox Code Playgroud)

注意:上面的7和8之间实际上有一个制表符,但是标记渲染似乎打破了它.

是的,那里有各种各样的疯狂.;-)

无论如何,我正在寻找这种转义扩展命令的反向.如果调用该命令escape,它将满足以下属性:

$ echo -ne "$(escape "$originalString")"
Run Code Online (Sandbox Code Playgroud)

应输出originalString' echo -n "$originalString"'' 的逐字值.即它应该是一个身份.

同样:

$ escape "$(echo -ne "$escapedString")"
Run Code Online (Sandbox Code Playgroud)

应该再次输出字符串转义,但不一定以与以前相同的方式.例如,\0134可能变成\\反之亦然.

Cha*_*ffy 6

不要使用echo -e- 它在POSIX中指定得很糟糕,并且除了最简单的用途之外被认为已被弃用.Bash对其进行了扩展printf,提供了更好的支持方法:

printf -v escaped_string %q "$raw_string"
Run Code Online (Sandbox Code Playgroud)

...从原始字符串中为您提供shell转义字符串(将其存储在名为的变量中escaped_string),以及

printf -v raw_string %b "$escaped_string"
Run Code Online (Sandbox Code Playgroud)

...给你一个反斜杠转义的原始字符串,存储它raw_string.


请注意,两个转义语法不相同 - 转义的字符串printf %q已准备就绪eval,而不是printf %b.

也就是说,您可以安全地运行:

eval "myvar=$escaped_string"
Run Code Online (Sandbox Code Playgroud)

... 如上所述escaped_string创建时printf %q.


那说:用例是什么?强烈建议将原始字符串作为原始字符串处理(在需要分隔时使用NUL终结符),而不是将它们转换为转义形式.