转义是一种引用单个字符的方法. 一个前面放上转义符 (\)的字符就是告诉shell这个字符按照字面的意思进行解释, 换句话说, 就是这个字符失去了它的特殊含义.
表示新的一行
表示回车
表示水平制表符
表示垂直制表符
表示后退符
表示"alert"(蜂鸣或者闪烁)
转换为八进制的ASCII码, 等价于0xx
例子 5-2. 转义符
1 #!/bin/bash 2 # escaped.sh: 转义符 3 4 echo; echo 5 6 echo "\v\v\v\v" # 逐字的打印\v\v\v\v. 7 # 使用-e选项的'echo'命令来打印转义符. 8 echo "=============" 9 echo "VERTICAL TABS" 10 echo -e "\v\v\v\v" # 打印4个垂直制表符. 11 echo "==============" 12 13 echo "QUOTATION MARK" 14 echo -e "\042" # 打印" (引号, 8进制的ASCII 码就是42). 15 echo "==============" 16 17 # 如果使用$'\X'结构,那-e选项就不必要了. 18 echo; echo "NEWLINE AND BEEP" 19 echo $'\n' # 新行. 20 echo $'\a' # 警告(蜂鸣). 21 22 echo "===============" 23 echo "QUOTATION MARKS" 24 # 版本2以后Bash允许使用$'\nnn'结构. 25 # 注意在这里, '\nnn\'是8进制的值. 26 echo $'\t \042 \t' # 被水平制表符括起来的引号("). 27 28 # 当然,也可以使用16进制的值,使用$'\xhhh' 结构. 29 echo $'\t \x22 \t' # 被水平制表符括起来的引号("). 30 # 感谢, Greg Keraunen, 指出了这点. 31 # 早一点的Bash版本允许'\x022'这种形式. 32 echo "===============" 33 echo 34 35 36 # 分配ASCII字符到变量中. 37 # ---------------------------------------- 38 quote=$'\042' # " 被赋值到变量中. 39 echo "$quote This is a quoted string, $quote and this lies outside the quotes." 40 41 echo 42 43 # 变量中的连续的ASCII字符. 44 triple_underline=$'\137\137\137' # 137是八进制的'_'. 45 echo "$triple_underline UNDERLINE $triple_underline" 46 47 echo 48 49 ABC=$'\101\102\103\010' # 101, 102, 103是八进制码的A, B, C. 50 echo $ABC 51 52 echo; echo 53 54 escape=$'\033' # 033 是八进制码的esc. 55 echo "\"escape\" echoes as $escape" 56 # 没有变量被输出. 57 58 echo; echo 59 60 exit 0 |
参考例子 34-1, 这是关于$' '字符串扩展结构的一个例子.
表示引号字面的意思
1 echo "Hello" # Hello 2 echo "\"Hello\", he said." # "Hello", he said. |
表示$本身子面的含义(跟在\$后边的变量名将不能引用变量的值)
1 echo "\$variable01" # 结果是$variable01 |
表示反斜线字面的意思
1 echo "\\" # 结果是\ 2 3 # 反之 . . . 4 5 echo "\" # 如果从命令行调用的话, 会出现SP2, 也就是2级提示符(译者注: 提示你命令不全, 在添加一个"就好了. 6 # 如果在脚本中调用的话, 那么会报错. |
\的行为依赖于它自身是否被转义, 被引用(""), 或者是否出现在命令替换或here document中.
赋值给变量的字符串的元素也会被转义, 但是不能把一个单独的转义符赋值给变量.
|
转义一个空格会阻止命令行参数列表的"单词分割"问题.
1 file_list="/bin/cat /bin/gzip /bin/more /usr/bin/less /usr/bin/emacs-20.7" 2 # 列出的文件都作为命令的参数. 3 4 # 加两个文件到参数列表中, 列出所有的文件信息. 5 ls -l /usr/X11R6/bin/xsetroot /sbin/dump $file_list 6 7 echo "-------------------------------------------------------------------------" 8 9 # 如果我们将上边的两个空个转义了会产生什么效果? 10 ls -l /usr/X11R6/bin/xsetroot\ /sbin/dump\ $file_list 11 # 错误: 因为前3个路径被合并成一个参数传递给了'ls -l' 12 # 而且两个经过转义的空格组织了参数(单词)分割. |
转义符也提供续行功能, 也就是编写多行命令的功能. 一般的, 每一个单独行都包含一个不同的命令, 但是每行结尾的转义符都会转义换行符, 这样下一行会与上一行一起形成一个命令序列.
1 (cd /source/directory && tar cf - . ) | \ 2 (cd /dest/directory && tar xpvf -) 3 # 重复Alan Cox的目录数拷贝命令, 4 # 但是分成两行是为了增加可读性. 5 6 # 也可以使用如下方式: 7 tar cf - -C /source/directory . | 8 tar xpvf - -C /dest/directory 9 # 察看下边的注意事项. 10 # (感谢, Stephane Chazelas.) |
如果一个脚本以|结束, 管道符, 那么就不用非的加上转义符\了. 但是一个好的编程风格, 还是应该在行尾加上转义符. |
1 echo "foo 2 bar" 3 #foo 4 #bar 5 6 echo 7 8 echo 'foo 9 bar' # 没什么区别. 10 #foo 11 #bar 12 13 echo 14 15 echo foo\ 16 bar # 换行符被转义. 17 #foobar 18 19 echo 20 21 echo "foo\ 22 bar" # 与上边一样, \在部分引用中还是被解释为续行符. 23 #foobar 24 25 echo 26 27 echo 'foo\ 28 bar' # 由于是全引用, 所以\没有被解释成续行符. 29 #foo\ 30 #bar 31 32 # 由Stephane Chazelas所建议的用例. |