bash中双引号与单引号的区别

来源:互联网 发布:微店好做还是淘宝好做 编辑:程序博客网 时间:2024/05/01 12:04

在 bash 中,常用的 quoting 有如下三种方法:
1) hard quote:' ' (单引号),凡在 hard quote 中的所有 meta 均被关闭。
2) soft quote: " " (双引号),在 soft quoe 中大部份 meta 都会被关闭,但某些则保留(如 $ )。

3) escape : \ (反斜线),只有紧接在 escape (转义字符)之后的单一 meta 才被关闭。
常用的meta
IFS:由 <space> 或 <tab> 或 <enter> 三者之一组成(我们常用 space )。
CR:由<enter> 产生。
    IFS 是用来拆解command line 的每一个词(word)用的,因为shell command line 是按词来处理的。
    而 CR 则是用来结束 command line 用的,这也是为何我们敲 <enter> 命令就会跑的原因。
除了 IFS 与 CR ,常用的 meta 还有:
= :  设定变量。
$ :  作变量或运算替换(请不要与 shell prompt 搞混了)。
> :重导向 stdout。
< :重导向 stdin。
|:命令管线。
& :重导向 file descriptor ,或将命令置于背境执行。
( ):将其内的命令置于 nested subshell 执行,或用于运算或命令替换。
{ }:将其内的命令置于 non-named function 中执行,或用在变量替换的界定范围。
; :在前一个命令结束时,而忽略其返回值,继续执行下一个命令。
&& :在前一个命令结束时,若返回值为 true,继续执行下一个命令。
|| :在前一个命令结束时,若返回值为 false,继续执行下一个命令。
!:执行 history 列表中的命令
....
例一:假设A=bbbb
jack@ubuntu:~$ echo -e "$A"    #echo -e 表示开启转义字符,否则如果你有\字符的号,它只是原样输出,而不会转义。
bbbb
jack@ubuntu:~$ echo -e '"$A"'      #最外面是单引号
"$A"
jack@ubuntu:~$ echo -e "'"$A"'"   #最外面是双引号
'bbbb'
首先看最外面是什么符号,单引号表示hard quote,双引号表示soft quote。
soft quote则$A就是变量啦;若是hard quote那直接就是字符串。
在 awk 或 sed 的命令参数中调用之前设定的一些变量时,常会问及为何不能的问题。
要解决这些问题,关键点就是:
区分出 shell meta 与 command meta
前面我们提到的那些 meta ,都是在 command line 中有特殊用途的,
比方说 { } 是将其内一系列 command line 置于不具名的函式中执行(可简单视为 command block ),
但是,awk 却需要用 { } 来区分出 awk 的命令区段(BEGIN, MAIN, END)。

若你在 command line 中如此输入:
$ awk {print $0} 1.txt
由于  {} 在 shell 中并没关闭,那 shell 就将 {print $0} 视为 command block ,
但同时又没有" ; "符号作命令区隔,因此就出现 awk 的语法错误结果。
要解决之,可用 hard quote :
$ awk '{print $0}' 1.txt
上面的 hard quote 应好理解,就是将原本的 {、<space>、$(注三)、} 这几个 shell meta 关闭,避免掉在 shell 中遭到处理,而完整的成为 awk 参数中的 command meta 。
( 注三:而其中的 $0 是 awk 内建的 field number ,而非  awk 的变量,awk 自身的变量无需使用 $ 。)
实际上可以写成:
awk"{print \$0}" 1.txt
awk \{print\ \$0\} 1.txt
但是现在我想把awk 的 $0 的 0 值是从另一个 shell 变量读进,怎么办?
如下方式可否:
$ awk '{print $$A}' 1.txt
答案不行,因为 $A 的 $ 在 hard quote 中是不能替换变量的。
使用awk外面的变量可这样:
A=0
1) awk "{print \$$A}" 1.txt
2) awk \{print\ \$$A\} 1.txt
3) awk '{print $'$A'}'1.txt      # $A没被任何引号隔开(不要以为两边有引号就是它的),所以实际上是shell变量啦。
4) awk '{print $'"$A"'}' 1.txt   #$A两边使用的是双引号,其它为单引号。
如果要在awk中输出外部变量怎么办?
看特殊形式:awk '{print "abc"}' #print后面的字符串要用双引号
一般形式: awk '{print "'$A'"}'   # $A左右两边都有单引号,其实就是上面的3)式。