shell十三问-4)   " "(双引号) 与 ' '(单引号)差在哪

�是回到我��的 command line �戆�...
��^前面�烧碌�W�,���很清楚��你在 shell prompt 後面敲打�I�P、直到按下 Enter 的�r候,
你�入的文字就是 command line 了,然後 shell 才��以行程的方式�绦心闼�交�o它的命令。
但是,你又可知道:你在 command line �入的每一��文字,�� shell �碚f,是有��e之分的呢?

��味�言(我不敢�f�@是精�_的定�h,�]一),command line 的每一�� charactor ,分�槿缦�煞N:
* literal:也就是普通�文字,�� shell �碚f�]特殊功能。
* meta:�� shell �碚f,具有特定功能的特殊保留字元。
(�]一:�P於 bash shell 在�理 command line �r的�序�f明,
��⒖� O'Reilly 出版社之 Learning the Bash Shell, 2nd Edition,第 177 - 180 �的�f明,
尤其是 178 �的流程�D Figure 7-1 ... )

Literal �]甚�N好�的,凡�e abcd、123456 �@些"文字"都是 literal ... (easy?)
但 meta �s常使我��困惑..... (confused?)
事��上,前�烧挛��在 command line 中已碰到����C乎每次都��碰到的 meta :
* IFS:由 <space> 或 <tab> 或 <enter> 三者之一�M成(我��常用 space )。
* CR:由 <enter> �a生。
IFS 是用�聿鸾� command line 的每一���~(word)用的,因�� shell command line 是按�~�硖�理的。
而 CR �t是用�斫Y束 command line 用的,�@也是�楹挝��敲 <enter> 命令就��跑的原因。
除了 IFS �c CR ,常用的 meta �有:
= :  �O定�量。
$ :  作�量或�\算替�Q(�不要�c shell prompt 搞混了)。
> :重��向 stdout。
< :重��向 stdin。
|:命令管�。
& :重��向 file descriptor ,或�⒚�令置於背境�绦小�
( ):�⑵�鹊拿�令置於 nested subshell �绦校�或用於�\算或命令替�Q。
{ }:�⑵�鹊拿�令置於 non-named function 中�绦校�或用在�量替�Q的界定���。
; :在前一��命令�Y束�r,而忽略其返回值,�^�m�绦邢乱��命令。
&& :在前一��命令�Y束�r,若返回值�� true,�^�m�绦邢乱��命令。
|| :在前一��命令�Y束�r,若返回值�� false,�^�m�绦邢乱��命令。
!:�绦� history 列表中的命令
....

假如我��需要在 command line 中�⑦@些保留字元的功能�P�]的�,就需要 quoting �理了。
在 bash 中,常用的 quoting 有如下三�N方法:
* hard quote:' ' (�我��),凡在 hard quote 中的所有 meta 均被�P�]。
* soft quote: " " (�p引�),在 soft quoe 中大部份 meta 都��被�P�],但某些�t保留(如 $ )。(�]二)
* escape : \ (反斜�),只有�o接在 escape (跳�字符)之後的�我� meta 才被�P�]。
( �]二:在 soft quote 中被豁免的具�w meta 清�危�我不完全知道,
有待大家�a充,或透�^��作�戆l�F及理解。 )

下面的例子�⒂兄�於我���� quoting 的了解:
 

  1.         $ A=B C        # 空白�I未被�P掉,作�� IFS �理。
     
  2.         $ C: command not found.
     
  3.         $ echo $A
     
  4.        
     
  5.         $ A="B C"        # 空白�I已被�P掉,�H作�榭瞻祖I�理。
     
  6.         $ echo $A
     
  7.         B C
复制代码


在第一次�O定 A �量�r,由於空白�I�]被�P�],command line �⒈唤庾x�椋�
* A=B 然後碰到<IFS>,再�绦� C 命令
在第二次�O定  A �量�r,由於空白�I被置於 soft quote 中,因此被�P�],不再作�� IFS :
* A=B<space>C
事��上,空白�I�o�在 soft quote �是在 hard quote 中,均��被�P�]。Enter �I亦然:
 

  1.         $ A='B
     
  2.         > C
     
  3.         > '
     
  4.         $ echo "$A"
     
  5.         B
     
  6.         C
复制代码


在上例中,由於 <enter> 被置於 hard quote ��中,因此不再作�� CR 字符�硖�理。
�@�e的 <enter> �渭�只是一���嘈蟹��(new-line)而已,由於 command line �K�]得到 CR 字符,
因此�M入第二�� shell prompt (PS2,以 > 符�表示),command line �K不���Y束,
直到第三行,我���入的 <enter> �K不在  hard quote �e面,因此�K�]被�P�],
此�r,command line 碰到 CR 字符,於是�Y束、交�o shell �硖�理。

上例的 <enter> 要是被置於 soft quote 中的�, CR 也��同�颖魂P�]:
 

  1.         $ A="B
     
  2.         > C
     
  3.         > "
     
  4.         $ echo $A
     
  5.         B C
复制代码


然而,由於 echo $A �r的�量�]至於 soft quote 中,因此���量替�Q完成後�K作命令行重�M�r,<enter> ��被解��� IFS ,而不是解��� New Line 字符。

同�拥模�用 escape 亦可�P�] CR 字符:
 

  1.         $ A=B\
     
  2.         > C\
     
  3.         >
     
  4.         $ echo $A
     
  5.         BC
复制代码


上例中,第一�� <enter> 跟第二�� <enter> 均被 escape 字符�P�]了,因此也不作�� CR �硖�理,
但第三�� <enter> 由於�]被跳�,因此作�� CR �Y束 command line 。
但由於 <enter> �I本身在 shell meta 中的特殊性,在 \ 跳�後面,�H�H取消其 CR 功能,而不��保留其 IFS 功能。

您或�S�l�F光是一�� <enter> �I所�a生的字符就有可能是如下�@些可能:
CR
IFS
NL(New Line)
FF(Form Feed)
NULL
...
至於甚�N�r候��解��樯觞N字符,�@��我就�]去深挖了,或是留�o�x者�T君自行慢慢摸索了... ^_^

至於 soft quote 跟 hard quote 的不同,主要是��於某些 meta 的�P�]�c否,以 $ �碜髡f明:
 

  1.         $ A=B\ C
     
  2.         $ echo "$A"
     
  3.         B C
     
  4.         $ echo '$A'
     
  5.         $A
复制代码


在第一�� echo 命令行中,$ 被置於 soft quote 中,�⒉槐魂P�],因此�^�m�理�量替�Q,
因此 echo �� A 的�量值�出到�赡唬�也就得到  "B C" 的�Y果。
在第二�� echo 命令行中,$ 被置於 hard quote 中,�t被�P�],因此 $ 只是一�� $ 符�,
�K不��用�碜髯�量替�Q�理,因此�Y果是 $ 符�後面接一�� A 字母:$A 。

--------------------------------------
���c思考:如下�Y果�楹尾煌�?
 

  1.         $ A=B\ C
     
  2.         $ echo '"$A"'        # 最外面的是�我��
     
  3.         "$A"
     
  4.         $ echo "'$A'"        # 最外面的是�p引�
     
  5.         'B C'
     
  6.         (提示:�我��及�p引�,在 quoting 中均被�P�]了。)
复制代码


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

在 CU 的 shell 版�e,我�l�F有很多初�W者的���},都�c quoting 理解的有�P。
比方�f,若我��在 awk 或 sed 的命令��抵姓{用之前�O定的一些�量�r,常����及�楹尾荒艿���}。
要解�Q�@些���},�P�I�c就是:
* �^分出 shell meta �c command meta

前面我��提到的那些 meta ,都是在 command line 中有特殊用途的,
比方�f { } 是�⑵�纫幌盗� command line 置於不具名的函式中�绦�(可��我��� command block ),
但是,awk �s需要用 { } ��^分出 awk 的命令�^段(BEGIN, MAIN, END)。
若你在 command line 中如此�入:
 

  1. $ awk {print $0} 1.txt
复制代码


由於  { } 在 shell 中�K�]�P�],那 shell 就�� {print $0} ��� command block ,
但同�r又�]有" ; "符�作命令�^隔,因此就出�F awk 的�Z法�e�`�Y果。

要解�Q之,可用 hard quote :
 

  1. $ awk '{print $0}' 1.txt
复制代码


上面的 hard quote ��好理解,就是�⒃�本的 {、<space>、$(�]三)、} �@��� shell meta �P�],
避免掉在 shell 中遭到�理,而完整的成�� awk ��抵械� command meta 。
( �]三:而其中的 $0 是 awk �冉ǖ� field number ,而非  awk 的�量,
awk 自身的�量�o需使用 $ 。)
要是理解了 hard quote 的功能,再�砝斫� soft quote �c escape 就不�y:
 

  1. awk "{print \$0}" 1.txt
     
  2. awk \{print\ \$0\} 1.txt
复制代码



然而,若你要改� awk 的 $0 的 0 值是�牧硪�� shell �量�x�M呢?
比方�f:已有�量 $A 的值是 0 ,那如何在 command line 中解�Q awk 的 $$A 呢?
你可以很直接否定掉 hard quoe 的方案:
 

  1. $ awk '{print $$A}' 1.txt
复制代码


那是因�� $A 的 $ 在 hard quote 中是不能替�Q�量的。

�明的�x者(如你!),��^本章�W�,我想,���可以解��楹挝��可以使用如下操作了吧:
 

  1. A=0
     
  2. awk "{print \$$A}" 1.txt
     
  3. awk \{print\ \$$A\} 1.txt
     
  4. awk '{print $'$A'}' 1.txt
     
  5. awk '{print $'"$A"'}' 1.txt     # 注:"$A" 包在 soft quote 中
复制代码



或�S,你能�e出更多的方案呢....  ^_^

--------------------------------------
���c思考:��\用本章�W到的知�R分析如下�纱���:
http://bbs.chinaunix.net/forum/viewtopic.php?t=207178
http://bbs.chinaunix.net/forum/viewtopic.php?t=216729
 

你可能感兴趣的:(shell,十三问)