引用
在shell中,引用的意思就是时讲字符串使用双拥好括起来,他的作用就是保护字符串中的特殊字符、不被shell或者shell脚本重新解释,或者扩展。
andrew@andrew:~$ ls -l [Ss]*
-rwx------ 1 andrew andrew 3849 1月 19 01:07 sources.list
andrew@andrew:~$ ls -l "[Ss]*"
ls: 无法访问'[Ss]*': 没有那个文件或目录
andrew@andrew:~$
某些程序和工具能够重新解释或者扩展被引用的特殊字符,引用的一个重要的作用就是保护命令行参数不被shell解释,但是还是能够让调用的程序来扩展它。
引用变量
在一个双引号中通过直接使用变量名的方法来引用变量,一般情况下都是没有问题的。这么做将阻止所有在引号中的特殊字符被重新解释 – 包括变量名 – 但是$
和\
除外。保持$
作为特殊字符的意义是为了能够在双引号中也能够正常引用比变量,也就是说变量在双引号中能够被他的值所取代。
使用双引号能够阻止单词分割,如果一个参数被双引号括起来的话,那么这个参数讲认为是一个单元,即使这个参数包含空白,那里面的单词也不会被分隔开。
# 定义一个变量
variable1="a variable containing five words"
# 在没有双引号的地方引用一个变量
COMMAND This is $variable1
# 用下面7个参数执行COMMAND命令:
# "This" "is" "a" "variable" "containing" "five" "words"
COMMAND "This is $variable1" # 用下面1个参数执行COMMAND命令:
# "This is a variable containing five words"
variable2=""
# Empty.
COMMAND $variable2 $variable2 $variable2
# COMMAND将不带参数执行.
COMMAND "$variable2" "$variable2" "$variable2" # COMMAND将以3个空参数来执行.
COMMAND "$variable2 $variable2 $variable2"
# COMMAND将以1个参数来执行(2空格).
使用echo输出一些诡异的变量
#!/bin/bash
# weirdvars.sh: echo出一些诡异变量.
var="'(]\\{}\$\""
echo $var
# '(]\{}$"
echo "$var"
# '(]\{}$"和上一句没什么区别.Doesn't make a difference.
echo
IFS='\'
echo $var
# '(] {}$"\ 字符被空白符替换了, 为什么?
# 双引号下,IFS特殊字符不能被替换
echo "$var"
# '(]\{}$"
# 这个例子由Stephane Chazelas提供.
exit 0
执行结果
andrew@andrew:/work/bash/src$ bash echo_unique.sh
'(]\{}$"
'(]\{}$"
'(] {}$"
'(]\{}$"
单引号(’ ‘)操作与双引号基本上一样,但是不允许引用变量,因为$的特殊意义被关闭了,在单引号中,任何特殊字符都按照字面的意思进行解释,除了’ 。所以单引号(全引用)是一种比双引号(双引号)更严格的引用方法。
因为即使是转义字符(
\
)在单引号中也是按照字面意思解释的,所以如果想在一对单引号中显示一个单引号是不行的(因为单引号的实现是按照就近原则完成的)。
echo "Why can't I write 's between single quotes"
echo
# 一种绕弯的方法.
echo 'Why can'\''t I write '"'"'s between single quotes'
#|-------| |----------||-----------------------|
# 三个被单引号引用的字符串, 在这三个字符串之间有一个用转义符转义的单引号, 和一个用双引号括起来的单引号.
显示单引号的两种方法
- 将单引号放置在双引号中
- 使用转义字符
andrew@andrew:/work/bash/src$ bash single_quotation_mark.sh
Why can't I write 's between single quotes
Why can't I write 's between single quotes
在echo中双引号中,使用!!的话,有可能会有意想不到的问题,因为!!是历史命令的意思,但是在脚本中使用!!没有问题,因为脚本中历史命令是被禁止的
转义
转义是一种引用单个字符的方法,一个前面放上转义字符(\
)的字符就是告诉shell这个字符按照字面的意思进行解释,换句话说,就是这个字符失去了它的特殊含义。
在某些特殊的命令和工具中,比如echo和sed,转义符往往会起到相反的效果 - 它反倒可能引发出这个字符的特殊含义。
特定转义符的特殊的含义
echo
和sed
命令中使用
\n
- 表示新的一行
\r
- 表示回车
\t
- 表示水平制表符号
\v
- 表示垂直制表符
\b
- 表示后退符号
\a
- 表示alert
蜂鸣或者闪烁
\0xx
- 转换为八进制的ASCII
码,等价于0xx
#!/bin/bash
# escaped.sh: 转义符
echo; echo
echo "\v\v\v\v"
# 逐字的打印\v\v\v\v.
# 使用-e选项的'echo'命令来打印转义符.
echo "============="
echo "VERTICAL TABS"
echo -e "\v\v\v\v"
# 打印4个垂直制表符.
echo "=============="
echo "QUOTATION MARK"
echo -e "\042"
# 打印" (引号, 8进制的ASCII 码就是42).
echo "=============="
# 如果使用$'\X'结构,那-e选项就不必要了.
echo; echo "NEWLINE AND BEEP"
echo $'\n'
# 新行.
echo $'\a'
# 警告(蜂鸣).21
echo "==============="
echo "QUOTATION MARKS"
# 版本2以后Bash允许使用$'\nnn'结构.
# 注意在这里, '\nnn\'是8进制的值.
echo $'\t \042 \t'
# 被水平制表符括起来的引号(").
# 当然,也可以使用16进制的值,使用$'\xhhh' 结构.
echo $'\t \x22 \t' # 被水平制表符括起来的引号(").
# 感谢, Greg Keraunen, 指出了这点.
# 早一点的Bash版本允许'\x022'这种形式.
echo "==============="
echo
# 分配ASCII字符到变量中.
# ----------------------------------------
quote=$'\042'
# " 被赋值到变量中.
echo "$quote This is a quoted string, $quote and this lies outside the quotes."
echo
# 变量中的连续的ASCII字符.
triple_underline=$'\137\137\137' # 137是八进制的'_'.
echo "$triple_underline UNDERLINE $triple_underline"
echo
ABC=$'\101\102\103\010'
# 101, 102, 103是八进制码的A, B, C.
echo $ABC
echo; echo
escape=$'\033'
# 033 是八进制码的esc.
echo "\"escape\" echoes as $escape"
#没有变量被输出.
echo; echo
exit 0
执行结果
andrew@andrew:/work/bash/src$ bash escape_charater.sh
# 在双引号中的转义符,将按照原样输出
\v\v\v\v
=============
VERTICAL TABS
==============
QUOTATION MARK
"
==============
NEWLINE AND BEEP
===============
QUOTATION MARKS
"
"
===============
" This is a quoted string, " and this lies outside the quotes.
___ UNDERLINE ___
ABC
"escape" echoes as
\"
表示引号字面意思
echo "hello" # hello
echo "\"hello\"" # "hello"
\$
- 输出$
自身的意思
\\
表示反斜线字面意思
echo "foo
bar"
#foo
#bar
echo
echo 'foo
bar'
# 没什么区别.
#foo
#bar
echo
echo foo\
bar
# 换行符被转义.
#foobar
echo
echo "foo\
bar"
# 与上边一样, \在部分引用中还是被解释为续行符.
#foobar
echo
echo 'foo\
bar'
# 由于是全引用, 所以\没有被解释成续行符.
#foo\
#bar