一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

linux shell中的單引號(hào)與雙引號(hào)的區(qū)別(看完就不會(huì)有引號(hào)的疑問了)

 李副營(yíng)長(zhǎng) 2015-01-01

" "(雙引號(hào))與 ' '(單引號(hào))的區(qū)別


  你在shell prompt(shell 提示)后面敲打鍵盤、直到按下enter的時(shí)候,你輸入的文字就是command line(命令行)了,然后shell才會(huì)以進(jìn)程方式執(zhí)行你所提交的命令。但是,你又可知道:你在command line輸入的每一個(gè)文字,對(duì)shell來說,有什么類別之分呢?

簡(jiǎn)單而言,command line的每一個(gè)charactor(字符)分為如下兩種:
  *literal(文字):也就是普通純文字,對(duì)shell來說沒有特殊功能。
  *meta(元字符):對(duì)shell來說,具有特定功能的保留字。
literal沒有什么好說的,凡是 abcd、123456 等這些“文字”都是literal。但是meta卻常使我們困惑。事實(shí)上,前兩章我們?cè)赾ommand line中已碰到兩個(gè)幾乎每次都會(huì)碰到的meta:
   *IFS(交換字段分隔符):由<space> <tab> <enter>三者之一組成(我們常用space)。
   *CR(回車鍵):由<enter>產(chǎn)生。
IFS是用來拆分command line的每一個(gè)詞(word)用的,因?yàn)閟hell command line是按詞來處理的。而CR則是用來結(jié)束command line用的,這也是為何我們敲<enter>命令就會(huì)執(zhí)行的原因。除了IFS和CR外,常用的meta還有:
= :  設(shè)定變量。
$ :  做變量或運(yùn)算替換(請(qǐng)不要與 shell prompt 搞混了)。
> :  重定向 stdout(標(biāo)準(zhǔn)輸出standard out)。
< :  重定向 stdin(標(biāo)準(zhǔn)輸入standard in)。
|:   管道命令。
& :  重定向 file descriptor (文件描述符),或?qū)⒚钪糜诤笈_(tái)執(zhí)行。
( ): 將其內(nèi)的命令置于 nested subshell (嵌套的子shell)執(zhí)行,或用于運(yùn)算或命令替換。
{ }: 將其內(nèi)的命令置于 non-named function(未命名函數(shù)) 中執(zhí)行,或用在變量替換的界定范圍。
; :  在前一個(gè)命令結(jié)束時(shí),而忽略其返回值,繼續(xù)執(zhí)行下一個(gè)命令。
&& : 在前一個(gè)命令結(jié)束時(shí),若返回值為 true,繼續(xù)執(zhí)行下一個(gè)命令。
|| : 在前一個(gè)命令結(jié)束時(shí),若返回值為 false,繼續(xù)執(zhí)行下一個(gè)命令。
!:   執(zhí)行 history 列表中的命令
....
假如我們要在command line中將這些保留元字符的功能關(guān)閉的話,就要用到 quoting (引用)處理了。
在bash中,我們常用的 quoting有如下三種方法:
   *hard quote:''(單引號(hào)),凡在hard quote中的所有meta均被關(guān)閉。
   *soft quote:""(雙引號(hào)),在soft quote中的大部分meta都會(huì)被關(guān)閉,但某些保留(如$)。
   *escape:\ (反斜線),只有緊接在escape(跳脫字符)之后的單一meta才被關(guān)閉。


下面的例子將有助于我們對(duì) quoting 的了解:

       $ A=B C        # 空白鍵未被關(guān)閉,作為IFS 處理。
       $ C: command not found.
       $ echo $A

       $ A="B C"        # 空白鍵已被關(guān)閉,僅作空白符號(hào)處理。
       $ echo $A
       B C

在第一次設(shè)定 A 變量時(shí),由于空白鍵沒有被關(guān)閉,command line 將被解讀為:
* A=B 然后碰到<IFS>,再執(zhí)行 C 命令
在第二次設(shè)定 A 變量時(shí),由于空白鍵置于 soft quote 中,因此被關(guān)閉,不再作為 IFS :
* A=B<space>C
事實(shí)上,空白鍵無論在 soft quote 還是在 hard quote 中,均會(huì)被關(guān)閉。Enter 鍵亦然:
       $ A='B
       > C
       > '
       $ echo "$A"
       B
       C

在上例中,由于 <enter> 被置于 hard quote 當(dāng)中,因此不再作為 CR 字符來處理。
這里的 <enter> 單純只是一個(gè)斷行符號(hào)(new-line)而已,由于 command line 并沒得到 CR 字符,
因此進(jìn)入第二個(gè) shell prompt (PS2,以 > 符號(hào)表示),command line 并不會(huì)結(jié)束,
直到第三行,我們輸入的 <enter> 并不在  hard quote 里面,因此并沒被關(guān)閉,
此時(shí),command line 碰到 CR 字符,于是結(jié)束、交給 shell 來處理。

上例的 <enter> 要是被置于 soft quote 中的話, CR 也會(huì)同樣被關(guān)閉:
       $ A="B
       > C
       > "
       $ echo $A
       B C

然而,由于 echo $A 時(shí)的變量沒置于 soft quote 中,因此當(dāng)變量替換完成后并作命令行重組時(shí),<enter> 會(huì)被解釋為 IFS ,而不是解釋為 New Line 字符。


同樣的,用 escape 亦可關(guān)閉 CR 字符:
       $ A=B\
       > C\
       >
       $ echo $A
       BC

上例中,第一個(gè) <enter> 跟第二個(gè) <enter> 均被 escape 字符關(guān)閉了,因此也不作為 CR 來處理,
但第三個(gè) <enter> 由于沒有被跳脫,因此作為 CR 結(jié)束 command line 。
但由于 <enter> 鍵本身在 shell meta 中的特殊性,在 \ 跳脫后面,僅僅取消其 CR 功能,而不會(huì)保留其 IFS 功能。

您或許發(fā)現(xiàn)光是一個(gè) <enter> 鍵所產(chǎn)生的字符就有可能是如下這些可能:
CR
IFS
NL(New Line)
FF(Form Feed)
NULL
...

至于 soft quote 跟 hard quote 的不同,主要是對(duì)于某些 meta 的關(guān)閉與否,以 $ 來作說明:
       $ A=B\ C
       $ echo "$A"
       B C
       $ echo '$A'
       $A

在第一個(gè) echo 命令行中,$ 被置于 soft quote 中,將不被關(guān)閉,因此繼續(xù)處理變量替換,
因此 echo 將 A 的變量值輸出到屏幕,也就得到  "B C" 的結(jié)果。
在第二個(gè) echo 命令行中,$ 被置于 hard quote 中,則被關(guān)閉,因此 $ 只是一個(gè) $ 符號(hào),
并不會(huì)用來作變量替換處理,因此結(jié)果是 $ 符號(hào)后面接一個(gè) A 字母:$A 。

---------------------------------------------------------
練習(xí)與思考:以下兩條命令輸出的結(jié)果分別是什么?
       $ A=B\ C
       $ echo '"$A"'        # 最外面的是單引號(hào)

       $ echo "'$A'"        # 最外面的是雙引號(hào)

----------------------------------------------------------------

【認(rèn)真閱讀文章,答案自會(huì)揭曉】

-------------------------------------------------------

下面為擴(kuò)展閱讀,難度有點(diǎn)大,初級(jí)同學(xué)建議學(xué)懂上面的就好。以后再做拓展也可以。

***************************************************************************************                                                          

在 CU 的 shell 版里,我發(fā)現(xiàn)有很多初學(xué)者的問題,都與 quoting 理解的有關(guān)。
比方說,若我們?cè)?awk 或 sed 的命令參數(shù)中調(diào)用之前設(shè)定的一些變量時(shí),常會(huì)問及為何不能的問題。
要解決這些問題,關(guān)鍵點(diǎn)就是:
* 區(qū)分出 shell meta 與 command meta

前面我們提到的那些 meta ,都是在 command line 中有特殊用途的,
比方說 { } 是將其內(nèi)一系列 command line 置于不具名的程序中執(zhí)行(可簡(jiǎn)單視為 command block ),
但是,awk 卻需要用 { } 來區(qū)分出 awk 的命令區(qū)段(BEGIN, MAIN, END)。
若你在 command line 中如此輸入:
1
2
3
[root@jasontest01 ~]# awk {print $0} 1.txt   #這里$0由shell解釋
awk: cmd. line:1: {print
awk: cmd. line:1:       ^ unexpected newline or end of string


由于  { } 在 shell 中并沒關(guān)閉,那 shell 就將 {print $0} 視為 command block ,
但同時(shí)又沒有" ; "符號(hào)作命令區(qū)隔,因此就出現(xiàn) awk 的語法錯(cuò)誤結(jié)果。

要解決之,可用 hard quote :

1
2
3
4
5
6
[root@jasontest01 ~]# awk '{print $0}' 1.txt    #而這里因?yàn)橛?'作用,所以$0其實(shí)是由awk程序解釋
i am student
my teacher is oldboy
i am very happy
i come from guangzhou
now i am in beijing


上面的 hard quote 應(yīng)好理解,就是將原本的 {、<space>、$(注三)、} 這幾個(gè) shell meta 關(guān)閉,
避免掉在 shell 中遭到處理,而完整的成為 awk 參數(shù)中的 command meta 。
( 注三:而其中的 $0 是 awk 內(nèi)建的 field number ,而非  awk 的變量,
awk 自身的變量無需使用 $ 。)
要是理解了 hard quote 的功能,再來理解 soft quote 與 escape 就不難:

1
2
3
4
5
6
[root@jasontest01 ~]# awk "{print \$0}" 1.txt
i am student
my teacher is oldboy
i am very happy
i come from guangzhou
now i am in beijing


1
2
3
4
5
6
[root@jasontest01 ~]# awk \{print\ \$0\} 1.txt
i am student
my teacher is oldboy
i am very happy
i come from guangzhou
now i am in beijing


然而,若你要改變 awk 的 $0 的 0 值是從另一個(gè) shell 變量讀進(jìn)呢?
比方說:已有變量 $A 的值是 0 ,那如何在 command line 中解決 awk 的 $$A 呢?
你可以很直接否定掉 hard quoe 的方案:

$ awk '{print $$A}' 1.txt

那是因?yàn)?$A 的 $ 在 hard quote 中是不能替換變量的。

聰明的讀者(如你!),經(jīng)過以上學(xué)習(xí),我想,應(yīng)該可以解釋為何我們可以使用如下操作了吧:

A=0
awk "{print \$$A}" 1.txt
awk \{print\ \$$A\} 1.txt
awk '{print $'$A'}' 1.txt      
#此處注意'的結(jié)合方式,前面的''結(jié)合,后面的‘’結(jié)合,下同
awk '{print $'"$A"'}' 1.txt     # 注:"$A" 包在 soft quote 中,,此處也要注意''與""的結(jié)合

單引號(hào)和雙引號(hào)都能關(guān)閉shell對(duì)特殊字符的處理。不同的是,雙引號(hào)沒有單引號(hào)嚴(yán)格,單引號(hào)關(guān)閉所有有特殊作用的字符,而雙引號(hào)只要求shell忽略大多數(shù),具體的說,就是①美元符號(hào)②反引號(hào)③反斜杠,這3種特殊字符不被忽略。 不忽略美元符號(hào)意味著shell在雙引號(hào)內(nèi)部也進(jìn)行變量名替換。

下面用一個(gè)簡(jiǎn)單的shell程序要說明一下。

1
2
3
4
5
6
7
8
9
10
11
12
13
debian:~/learn/shell# cat phonebook
Alice Chebba 973-555-2015
Barbara Swingle 201-555-9257
Liz Stachiw 212-555-2298
Susan Goldberg 201-555-7776
Susan Topple 212-555-4932
Tony Iannino 973-555-1295
Stromboli Pizza 973-555-9478
debian:~/learn/shell#
debian:~/learn/shell# cat lu
# Look someone up in the phone book
grep "$1" phonebook
debian:~/learn/shell#

這是正確的lu程序,下面是運(yùn)行結(jié)果。

1
2
3
4
5
debian:~/learn/shell# ./lu 'Susan T'
Susan Topple 212-555-4932
debian:~/learn/shell# ./lu Tony
Tony Iannino 973-555-1295
debian:~/learn/shell#

如果lu寫成①grep $1 phonebook或者②grep '$1' phonebook,就會(huì)出現(xiàn)下面的錯(cuò)誤結(jié)果(為什么?)。

①的結(jié)果:

1
2
3
4
5
6
7
debian:~/learn/shell# ./lu Tony //這種情況結(jié)果正確
Tony Iannino 973-555-1295
debian:~/learn/shell# ./lu 'Susan T' //這種情況結(jié)果錯(cuò)誤
grep: T: No such file or directory
phonebook:Susan Goldberg 201-555-7776
phonebook:Susan Topple 212-555-4932
debian:~/learn/shell#

②的結(jié)果:

1
2
3
debian:~/learn/shell# ./lu Tony //這種情況結(jié)果錯(cuò)誤
debian:~/learn/shell# ./lu 'Susan T' //這種情況結(jié)果也錯(cuò)誤
debian:~/learn/shell#


————————————————————————————————

輸出結(jié)果:(思考,為什么不同?)

$ A=B\ C

$ echo '"$A"'        # 最外面的是單引號(hào)

"$A"
$ echo "'$A'"        # 最外面的是雙引號(hào)
'B C'

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多

    欧美日韩有码一二三区| 国产成人精品一区二区三区| 热情的邻居在线中文字幕| 中文字幕佐山爱一区二区免费| 国产一区欧美一区日韩一区| 亚洲国产一区精品一区二区三区色| 免费亚洲黄色在线观看| 日韩精品日韩激情日韩综合| 老司机精品一区二区三区| 欧美日韩人妻中文一区二区| 国产精品制服丝袜美腿丝袜| 国产午夜精品在线免费看| 日韩精品中文在线观看| 亚洲中文字幕视频一区二区| 亚洲成人精品免费在线观看| 精品综合欧美一区二区三区| 日韩三级黄色大片免费观看| 国产日韩中文视频一区| 女生更色还是男生更色 | 欧美高潮喷吹一区二区| 国产日韩精品激情在线观看| 黄片在线免费看日韩欧美| 亚洲精品成人福利在线| 日本一品道在线免费观看| 91久久精品国产成人| 日韩高清中文字幕亚洲| 欧美韩日在线观看一区| 东京不热免费观看日本| 欧美黄色成人真人视频| 又黄又硬又爽又色的视频| 尹人大香蕉中文在线播放| 亚洲精品福利入口在线| 亚洲一区二区久久观看| 久热人妻中文字幕一区二区| 亚洲精品国产第一区二区多人| 国产一区二区精品高清免费 | 91精品视频免费播放| 久久99午夜福利视频| 精品亚洲香蕉久久综合网| 老司机精品视频在线免费看 | 国产中文字幕一二三区|