----------- 转义是一种引用单个字符的方法.一个具有特殊含义的字符前边放上一个转义符(\)就告诉shell 这个字符失去了特殊的含义. 值得注意的是,在某些特定的命令和工具中,比如echo和sed,转义符往往会起到相反的效果, 它反倒有可能引发出这个字符特殊的含义.
对于特定的转义符的特殊的含义 在echo和sed中所使用的 \n 意味着新的一行 \r 回车 \t tab键 \v vertical tab(垂直tab),查前边的Ctl-K \b backspace,查前边的Ctl-H \a "alert"(如beep或flash) \0xx 转换成8进制ASCII解码,等价于oxx
Example 5-2 转义符 ################################Start Script####################################### 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" # Prints 4 vertical tabs. 11 echo "==============" 12 13 echo "QUOTATION MARK" 14 echo -e "\042" # 打印" (引号, 8进制的ASCII 码就是42). 15 echo "==============" 16 17 # The $'\X' construct makes the -e option unnecessary. 17 # 如果使用$'\X'结构,那-e选项就不必要了 18 echo; echo "NEWLINE AND BEEP" 19 echo $'\n' # 新行. 20 echo $'\a' # Alert (beep). 21 22 echo "===============" 23 echo "QUOTATION MARKS" 24 # 版本2以后Bash允许使用$'\nnn'结构 25 # 注意这种情况,'\nnn\是8进制 26 echo $'\t \042 \t' # Quote (") framed by tabs. 27 28 # 当然,也可以使用16进制的值,使用$'\xhhh' 结构 29 echo $'\t \x22 \t' # Quote (") framed by tabs. 30 31 # 早一点的Bash版本允许'\x022'这种形式 32 echo "===============" 33 echo 34 35 36 # 分配ASCII字符到变量中 37 # --------------------- 38 quote=$'\042' # \042是",分配到变量中 39 echo "$quote This is a quoted string, $quote and this lies outside the quotes." 40 41 echo 42 43 # Concatenating ASCII chars in a variable. 43 # 变量中的连续的ASCII char. 44 triple_underline=$'\137\137\137' # 137 是8进制的ASCII 码'_'. 45 echo "$triple_underline UNDERLINE $triple_underline" 46 47 echo 48 49 ABC=$'\101\102\103\010' # 101, 102, 103 是8进制的码A, B, C. 50 echo $ABC 51 52 echo; echo 53 54 escape=$'\033' # 033 是8进制码for escape. 55 echo "\"escape\" echoes as $escape" 56 #"escape" echoes as 没有变量被输出 57 58 echo; echo 59 60 exit 0 ################################End Script######################################### 另一个关于$''字符串扩展结果的例子见Example 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 "\" # 这会出现第2个命令提示符,说白了就是提示你命令不全,你再补个"就 6 # 好了.如果是在脚本里,就会给出一个错误.
注意:\的行为依赖于它是否被转义,被"",或者是否在"命令替换"和"here document"中. ################################Start Script####################################### 1 # 简单的转义和"" 2 echo \z # z 3 echo \\z # \z 4 echo '\z' # \z 5 echo '\\z' # \\z 6 echo "\z" # \z 7 echo "\\z" # \z 8 9 # 命令替换 10 echo `echo \z` # z 11 echo `echo \\z` # z 12 echo `echo \\\z` # \z 13 echo `echo \\\\z` # \z 14 echo `echo \\\\\\z` # \z 15 echo `echo \\\\\\\z` # \\z 16 echo `echo "\z"` # \z 17 echo `echo "\\z"` # \z 18 19 # Here document 20 cat <<EOF 21 \z 22 EOF # \z 23 24 cat <<EOF 25 \\z 26 EOF # \z ################################End Script#########################################
分配给变量的字符串的元素也会被转义,但是只把一个转义符分配给变量将会报错. ################################Start Script####################################### 1 variable=\ 2 echo "$variable" 3 # Will not work - gives an error message: 3 # 将不能正常工作- 将给出一个错误消息: 4 # test.sh: : command not found 5 # 一个"裸体的" 转义符将不能够安全的分配给变量. 6 # 7 # What actually happens here is that the "\" escapes the newline and 7 # 这里其实真正发生的是variable=\,这句被shell认为是没有完成,\被认为是一个续行符 8 #+ 这样,下边的这句echo,也被认为是上一行的补充.所以,总的来说就是一个非法变量分配 9 10 variable=\ 11 23skidoo 12 echo "$variable" # 23skidoo 13 # 这句就可以使用,因为这是一个合法的变量分配 14 15 variable=\ 16 # \^ 转义一个空格 17 echo "$variable" # 显示空格 18 19 variable=\\ 20 echo "$variable" # \ 21 22 variable=\\\ 23 echo "$variable" 24 # 不能正常工作,给出一个错误 25 # test.sh: \: command not found 26 # 27 # 第一个转义符把第2个\转义了,但是第3个又变成"裸体的"了, 28 #+ 与上边的例子的原因相同 29 30 variable=\\\\ 31 echo "$variable" # \\ 32 # 转了两个\ 33 # 没问题 ################################End Script#########################################
转义一个空格,在命令行参数列表中将会阻止单词分隔问题. ################################Start Script####################################### 1 file_list="/bin/cat /bin/gzip /bin/more /usr/bin/less /usr/bin/emacs-20.7" 2 # 列出的文件都作为命令的参数. 3 4 # Add two files to the list, and list all. 4 # 加2个文件到list中,并且列出全部. 5 ls -l /usr/X11R6/bin/xsetroot /sbin/dump $file_list 6 7 echo "-------------------------------------------------------------------------" 8 9 # 如果我们转义2个空格,会发生什么? 10 ls -l /usr/X11R6/bin/xsetroot\ /sbin/dump\ $file_list 11 # 错误: 因为前3个路径名被合并成一个参数传给了'ls -l' 12 # 因为2个转义符阻止了参数(单词)分离 ################################End Script#########################################
转义符也提供续行功能.一般,每一行都包含一个不同的命令,但如果在行尾加上\,那就会接受 新行的输入,作为这一行的补充. 1 (cd /source/directory && tar cf - . ) | \ 2 (cd /dest/directory && tar xpvf -) 3 # 重复了 Alan Cox的目录树拷贝命令 4 # 为了增加可读性分成2行. 5 6 # 也可以使用如下方式: 7 tar cf - -C /source/directory . | 8 tar xpvf - -C /dest/directory 9 # 察看下边的注意事项
注意:如果一个脚本以|(管道字符)结束.那么一个\(转义符),就不用非加上不可了. 但是一个好的shell脚本编写风格,还是应该在行尾加上\,以增加可读性. ################################Start Script####################################### 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 ################################End Script######################################### |