【问题标题】:How does one ‘contract’ strings to escape special characters in Bash?一个“合同”字符串如何转义 Bash 中的特殊字符?
【发布时间】:2014-07-24 06:29:36
【问题描述】:

扩展转义字符串的方法有很多,但是如何让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)$ 

注意:上面的 7 和 8 之间其实有一个制表符,但是标记渲染好像把它打断了。

是的,里面有各种各样的疯狂。 ;-)

无论如何,我正在寻找这种转义扩展命令的反面。如果该命令被称为escape,它将满足以下属性:

$ echo -ne "$(escape "$originalString")"

应该像“echo -n "$originalString"”一样输出originalString 的逐字值。 IE。它应该是一个身份。

同样:

$ escape "$(echo -ne "$escapedString")"

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

【问题讨论】:

    标签: string bash escaping


    【解决方案1】:

    不要使用echo -e——它在 POSIX 中的规定非常差,除了最简单的用途外,它被认为已弃用。 Bash 对其printf 进行了扩展,提供了更好的支持方法:

    printf -v escaped_string %q "$raw_string"
    

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

    printf -v raw_string %b "$escaped_string"
    

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


    请注意,这两种转义语法并不等效——用printf %q 转义的字符串准备好用于eval,而不是printf %b

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

    eval "myvar=$escaped_string"
    

    ...当escaped_string 已使用printf %q 如上所述创建时。


    也就是说:用例是什么?强烈推荐将原始字符串作为原始字符串处理(在需要定界时使用 NUL 终止符),而不是将它们转换为转义形式。

    【讨论】:

    • 谢谢!我查看了printf 联机帮助页,但不幸的是它甚至没有提到%q。 Bash 的手册页在 SHELL BUILTIN COMMANDS 下提到了它; printf 手册页是 GNU Coreutils,不幸的是它不关心手册页。感谢您指出 echo -e 弃用;从现在开始,我会尽量养成使用printf 而不是echo 的习惯。
    • 我实际上是在问,因为我不想使用 NUL 作为分隔符,因为原始字符串中可能包含任何字符,但如果是,则绝对不能使用 eval跨越特权边界的转义字符串。真的没有printf %b 的直接逆,或者printf %q 的逆不依赖转义输入来保证安全吗?
    • @JamesHaigh,当您说“任何”字符时,您的意思是包括 NUL?您不能将 NUL 存储在标准 bash 标量变量中,因此我不知道您如何期望可以处理包含 NUL 的数据的非转义函数或方法工作,除非它写入数组而不是字符串。
    • ...所以,f'rinstance,如果您在一个数组中表示包含 NUL 的字节字符串(每个 NUL 作为元素边界),那么序列化/反序列化很容易:写数组长度,然后是 NUL 分隔的值,你就完成了;阅读是完全相反的,没有要处理的特权问题。
    • ...如果您想了解如何做到这一点的详细信息,并且还没有确切的答案,请随时将其写成一个单独的问题并指向我。 :)
    猜你喜欢
    • 1970-01-01
    • 2011-05-11
    • 2011-05-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-02
    • 2017-11-30
    • 1970-01-01
    相关资源
    最近更新 更多