Shell中引用是用于去除某些字符的特殊含义, 而使其回归字面意思. 引用可以防止扩展(参数扩展,路径扩展等), 命令替换以及here-document的发生.
在Shell至少以下字符(字符后面括号中文字解释其用途)是特殊的, 所以如果想要这些字符的字面意思, 就需要引用:
|(管道) &(后台执行) ;(命令分隔符) <和>(重定向) (和)(子进程) `(命令替换) $(变量/参数扩展) \(转义/行继续) "(引用) '(引用) (参数分隔符) (参数分隔符) (行分隔符)
以下字符可能需要引用, 他们是否表示字面意思得看条件:
* ? [ 这3个是glob模式匹配字符, 当模式匹配能够发生时, 这些字符将失去字面意思. 比如对命令echo ab* 若当前目录下存在ab开头的文件(或目录), 则该命令输出这些文件/目录的名称(所以*失去字面意思), 而当不存在此类文件或目录时, 该命令仅输出ab*(即*取字面意思). 对?和[也是一样的.
% 对于支持作业控制shell实现(如csh,bash)而言, %后加数字表示指定的作业, 除此之外%表示百分号字符而已(字面意思)
# 当其作为某命令行第一个非空字符出现时, 其表示注释(非字面意思), 否则取字面意思.
= 当name=value出现在实际命令之前时, 其表示赋值(当赋值后无命令时, 该赋值将一直有效直到再次赋值或取消变量; 当赋值后有命令时, 该赋值仅对紧随命令有效, 比如n1=v1 ls中n1=v1仅在执行此条ls时有效), 其他情况下, 其表示等号.
~ 单独使用表示当前用户HOME目录, 当后面跟用户名时表示该用户HOME目录, 否则取字面意思.
引用的机制有: 使用转义符, 使用单引号, 使用双引号, here-document.
1 转义符(反斜杠\)
反斜杠使紧接其后的那个字符取字面意思, 当紧接字符本来就无特殊意义时, 该转义符被忽略. 唯一的例外是后接(即换行符). 当后面为换行符时, 表示行继续, 即紧接的行内容将加到当前命令行的末尾, 在对新的当前命令行进行符号分解之前, 换行符和反斜杠都将被删除. 由于换行符被删除, 所以该换行符将不能作为符号分隔符.
比如 echo abc\
def
实际的命令将是echo abcdef, 如果想要保证行继续前有空格分隔, 一般应当在\之前就添加空格.
2 单引号
所有在一对单引号中的字符都表现出字面意思. 只有单引号本身不可出现在一对单引号中.
3 双引号
在一对双引号中的大部分字符可以表现出字面意思, 除了以下:
$ 该符号仍然可以用于执行参数扩展(即取参数值, 包含位置参数和正常参数), 命令替换(比如$(command)等, 表达式将被command的输出所替代), 以及算术表达式扩展($((expr)),该表达式将被expr的最终结果所替代)
` 反引号用于进行命令替换, `command`将被command的输出所替代.
\ 该字符只有当其后跟着下列字符时, 其才具有转义字符的含义:
$ ` " \
此说明在双引号对中可以有双引号, 只要用\前置即可.
4 Here-document
重定向操作符<<和<<-允许将脚本中一系列行重定向到一个命令的某个文件描述符, 该一系列行将作为一个整体, 被称为here-document, 其格式为:
[n] << word
here-document
delimiter
其中n表示要被重定向的那个文件描述符, 如果省略, 则默认是0, 表示标准输入.
如果word中的任何字符被引用, 则delimeter应是word的去引用版本, 且here-document中将不会有任何扩展发生. 否则, delimiter应与word相同, 且允许扩展(包含参数扩展, 命令替换和数学表达式扩展).
比如有 name=value 则对于
cat <<"EOF"
name is $name
EOF
其结果为name is $name
而对于
cat <
name is $name
EOF
其结果则为name is value
here-document中的双引号将不具有引用的含义, 除非该双引号在$(), ``或 ${}中, 且该here-document允许这些扩展发生.
如果重定向符号是<<-, 则所有行中开始的序列都会被剔除. 如果<<和<<-都使用的话, 第一个出现的起作用
阅读(1296) | 评论(0) | 转发(0) |