哪些字符需要在Bash中转义? 我们怎么知道它?
是否有需要在Bash中转义的字符的全面列表? 可以用sed
检查吗?
特别是,我正在检查是否需要转义%
。 我试过了
echo "h%h" | sed 's/%/i/g'
并工作得很好,没有逃脱%
。 这是否意味着%
不需要被转义? 这是检查必要性的好方法吗?
而更一般的:他们是相同的字符在shell
和bash
逃脱吗?
有两个简单而安全的规则,不仅适用于sh
,也适用于bash
。
1.把整个string放在单引号中
这适用于除单引号之外的所有字符。 要转义单引号,请先closures引号,插入单引号,然后重新打开引号。
'I'\''mas@fe $tring which ends in newline '
sed命令: sed -e "s/'/'\\\\''/g; 1s/^/'/; \$s/\$/'/"
2.用反斜杠将每个字符都转义出来
这适用于除了换行符之外的所有字符。 换行符使用单引号或双引号。 必须仍然处理空string – 用""
replace
\I\'\m\ \a\ \s\@\f\e\ \$\t\r\i\n\g\ \w\h\i\c\h\ \e\n\d\s\ \i\n\ \n\e\w\l\i\n\e" "
sed命令: sed -e 's/./\\&/g; 1{$s/^$/""/}; 1!s/^/"/; $!s/$/"/'
sed -e 's/./\\&/g; 1{$s/^$/""/}; 1!s/^/"/; $!s/$/"/'
sed -e 's/./\\&/g; 1{$s/^$/""/}; 1!s/^/"/; $!s/$/"/'
。
2B。 更可读的版本2
有一个简单安全的字符集,如[a-zA-Z0-9,._+:@%/-]
,可以不加转义地保持它的可读性
I\'m\ a\ s@fe\ \$tring\ which\ ends\ in\ newline" "
sed命令: LC_ALL=C sed -e 's/[^a-zA-Z0-9,._+@%/-]/\\&/g; 1{$s/^$/""/}; 1!s/^/"/; $!s/$/"/'
LC_ALL=C sed -e 's/[^a-zA-Z0-9,._+@%/-]/\\&/g; 1{$s/^$/""/}; 1!s/^/"/; $!s/$/"/'
LC_ALL=C sed -e 's/[^a-zA-Z0-9,._+@%/-]/\\&/g; 1{$s/^$/""/}; 1!s/^/"/; $!s/$/"/'
。
请注意,在sed程序中,不能确定最后一行input是否以换行符结束(除非是空的)。 这就是为什么上面的sed命令都假设没有。 您可以手动添加带引号的换行符。
请注意,shellvariables只是为POSIX意义上的文本定义的。 处理二进制数据没有定义。 对于那些重要的实现,除了NUL字节之外,二进制文件是可以工作的(因为variables是用Cstring实现的,并且用作Cstring,也就是程序参数),但是你应该切换到一个“二进制”的语言环境,例如latin1 。
(您可以通过阅读sh
的POSIX规范来轻松validation规则。对于bash,请查看@AustinPhillips链接的参考手册)
要保存其他人从RTFM …在bash中 :
用双引号括起来的字符保留了引号中所有字符的字面值,除了
$
,`
,\
,并且当启用历史扩展时,!
。
…所以,如果你逃避了这些(当然还有引用本身),你可能没问题。
如果采取更加保守的“有疑问,逃避”的方法,应该可以通过不转义标识符字符(即ASCII字母,数字或'_')来避免取得具有特殊含义的字符。 这是不太可能的(即在一些奇怪的POSIX-ishshell中)具有特殊的含义,因此需要逃脱。
在Bourne或POSIX shell中,需要转义的字符与Bash不同。 一般来说(非常)Bash是这些炮弹的超集,所以你在shell
中逃跑的任何东西都应该在Bash中逃脱。
一个很好的通用规则是“如果有疑问,逃避它”。 但是逃脱某些angular色给了他们一个特殊的含义,比如\n
。 这些被列在Quoting
和echo
下的man bash
页面中。
除此之外,逃避任何不是字母数字的字符,更安全。 我不知道一个确切的清单。
手册页列出所有的地方,但不在一个地方。 学习语言,这是可以肯定的。
一个让我出去的是!
。 这是Bash(和csh)中的一个特殊字符(历史扩展),但不是在Korn shell中。 甚至echo "Hello world!"
给出问题。 像往常一样使用单引号,删除了特殊的含义。
格式,可以重新用作shellinput
为这种请求构build了一个特殊的 printf
格式指令( %q
):
printf [-v var]格式[参数]
%q causes printf to output the corresponding argument in a format that can be reused as shell input.
一些样品:
read foo Hello world printf "%q\n" "$foo" Hello\ world printf "%q\n" $'Hello world!\n' $'Hello world!\n'
这也可以通过variables来使用:
printf -v var "%q" "$foo " echo "$var" $'Hello world\n'
我假定你在讨论bashstring。 有不同types的string有不同的转义要求。 例如。 单引号string与双引号string不同。
最好的参考是bash手册的引用部分。
它解释了哪些字符需要转义。 请注意,某些字符可能需要转义,具体取决于启用了哪些选项,如历史扩展。
我注意到,使用自动完成时,bash会自动转义一些字符。
例如,如果您有一个名为dir:A
的目录,bash将自动完成到dir\:A
使用这个,我跑了一些使用ASCII表格的字符的实验,并得出以下列表:
bash在自动完成时逃脱的字符 :(包括空格)
!"$&'()*,:;<=>?@[\]^`{|}
bash不能逃脱的字符 :
#%+-.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz~
(我排除/
,因为它不能在目录名称中使用)
使用print '%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的投入。