在Bash中是否有需要转义的字符的综合列表?仅仅用sed可以检查吗?

特别是,我正在检查%是否需要转义。我试着

echo "h%h" | sed 's/%/i/g'

并工作良好,没有逃脱%。这是否意味着%不需要转义?这是检查必要性的好方法吗?

更一般的是:它们是shell和bash中转义的相同字符吗?


当前回答

我注意到bash在使用自动完成时自动转义一些字符。

例如,如果你有一个名为dir: a的目录,bash会自动补全到dir\: a

使用这个,我运行了一些实验,使用ASCII表的字符,并推导出以下列表:

bash自动完成转义的字符:(包括空格)

 !"$&'()*,:;<=>?@[\]^`{|}

bash没有转义的字符:

#%+-.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz~

(我排除了/,因为它不能在目录名中使用)

其他回答

在Bourne或POSIX shell中需要转义的角色与Bash不同。通常(very) Bash是这些shell的超集,所以在shell中转义的任何内容都应该在Bash中转义。

一个很好的一般规则是“如果有疑问,逃避它”。但是转义某些字符会赋予它们特殊的含义,比如\n。这些在引用和回声下的man bash页面中列出。

除此之外,转义任何非字母数字的字符更安全。我不知道一个明确的清单。

手册页在某个地方列出了它们,但不是在一个地方。学习语言,那是必胜之道。

其中一个让我大吃一惊的是!这是Bash(和csh)中的一个特殊字符(历史扩展),但在Korn shell中不是。即使是回音“Hello world!”也会出问题。像往常一样,使用单引号就去掉了特殊含义。

我猜你说的是bash字符串。有不同类型的字符串,它们对转义有不同的要求。如。单引号字符串不同于双引号字符串。

最好的参考是bash手册的引用部分。

它解释了哪些字符需要转义。注意,某些字符可能需要转义,这取决于启用了哪些选项,如历史扩展。

为了不让别人不得不RTFM…在bash中:

用双引号括起来的字符会保留引号内所有字符的文字值,除了$、'、\和(当启用历史扩展时)!

...所以如果你转义了这些(当然还有引用本身),你可能就没事了。

如果你采取更保守的“当有疑问时,转义它”的方法,应该可以通过不转义标识符字符(即ASCII字母、数字或“_”)来避免获得具有特殊含义的字符。这是非常不可能的(即在一些奇怪的posix shell中)有特殊的含义,因此需要转义。

我注意到bash在使用自动完成时自动转义一些字符。

例如,如果你有一个名为dir: a的目录,bash会自动补全到dir\: a

使用这个,我运行了一些实验,使用ASCII表的字符,并推导出以下列表:

bash自动完成转义的字符:(包括空格)

 !"$&'()*,:;<=>?@[\]^`{|}

bash没有转义的字符:

#%+-.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz~

(我排除了/,因为它不能在目录名中使用)

使用打印'%q'技术,我们可以运行一个循环来找出哪些字符是特殊的:

#!/bin/bash
special=$'`!@#$%^&*()-_+={}|[]\\;\':",.<>?/ '
for ((i=0; i < ${#special}; i++)); do
    char="${special:i:1}"
    printf -v q_char '%q' "$char"
    if [[ "$char" != "$q_char" ]]; then
        printf 'Yes - character %s needs to be escaped\n' "$char"
    else
        printf 'No - character %s does not need to be escaped\n' "$char"
    fi
done | sort

它给出如下输出:

No, character % does not need to be escaped
No, character + does not need to be escaped
No, character - does not need to be escaped
No, character . does not need to be escaped
No, character / does not need to be escaped
No, character : does not need to be escaped
No, character = does not need to be escaped
No, character @ does not need to be escaped
No, character _ does not need to be escaped
Yes, character   needs to be escaped
Yes, character ! needs to be escaped
Yes, character " needs to be escaped
Yes, character # needs to be escaped
Yes, character $ needs to be escaped
Yes, character & needs to be escaped
Yes, character ' needs to be escaped
Yes, character ( needs to be escaped
Yes, character ) needs to be escaped
Yes, character * needs to be escaped
Yes, character , needs to be escaped
Yes, character ; needs to be escaped
Yes, character < needs to be escaped
Yes, character > needs to be escaped
Yes, character ? needs to be escaped
Yes, character [ needs to be escaped
Yes, character \ needs to be escaped
Yes, character ] needs to be escaped
Yes, character ^ needs to be escaped
Yes, character ` needs to be escaped
Yes, character { needs to be escaped
Yes, character | needs to be escaped
Yes, character } needs to be escaped

有些结果,看起来有点可疑。获得@CharlesDuffy在这方面的投入会很有趣。