shell 十三問:
1) 爲什麼叫作 shell ?
2) shell prompt(PS1) 與 Carriage Return(CR) 的關係?
3) 別人 echo、你也 echo ,是問 echo 知多少?
4) " "(雙引號) 與 ' '(單引號)差在哪?
5) var=value?export 先後差在哪?
6) exec 跟 source 差在哪?
7) ( ) 與 { } 差在哪?
8) $(( )) 與 $( ) 還有${ } 差在哪?
9) $@ 與 $* 差在哪?
10) && 與 || 差在哪?
11) >; 與 < 差在哪?
12) 你要 if 仍是 case 呢?
13) for what? while 與 until 差在哪?
------------------------------------------------------------------------------------------------------------
1) 爲什麼叫作 shell ?
在介紹 shell 是甚麼東西以前,不妨讓咱們從新檢視使用者與計算機系統的關係:
咱們知道計算機的運做不能離開硬件,但使用者卻沒法直接對硬件做驅動,硬件的驅動只能透過一個稱爲"操做系統(Operating System)"的軟件來控管,事實上,咱們天天所談的 linux ,嚴格來講只是一個操做系統,咱們稱之爲"核心(kernel)"。然而,從使用者的角度來講,使用者也沒辦法直接操做 kernel ,而是透過 kernel 的"外殼"程序,也就是所謂的 shell ,來與 kernel 溝通。這也正是 kernel 跟 shell 的形像命名關係。
從技術角度來講,shell 是一個使用者與系統的互動界面(interface),主要是讓使用者透過命令行(command line)來使用系統以完成工做。所以,shell 的最簡單的定義就是---命令解譯器(Command Interpreter):
* 將使用者的命令翻譯給核心處理,
* 同時,將核心處理結果翻譯給使用者。
每次當咱們完成系統登入(log in),咱們就取得一個互動模式的 shell ,也稱爲 login shell 或 primary shell。若從行程(process)角度來講,咱們在 shell 所下達的命令,均是 shell 所產生的子行程。這現像,咱們暫可稱之爲 fork 。若是是執行腳本(shell script)的話,腳本中的命令則是由另一個非互動模式的子 shell (sub shell)來執行的。也就是 primary shell 產生 sub shell 的行程,sub shell 再產生 script 中全部命令的行程。
(關於行程,咱們往後有機會再補充。)
這裏,咱們必須知道:kernel 與 shell 是不一樣的兩套軟件,並且都是能夠被替換的:
* 不一樣的操做系統使用不一樣的 kernel ,
* 而在同一個 kernel 之上,也可以使用不一樣的 shell 。
在 linux 的預設系統中,一般均可以找到好幾種不一樣的 shell ,且一般會被列於以下檔案裏:
/etc/shells
不一樣的 shell 有着不一樣的功能,且也彼此各異、或說"大同小異"。常見的 shell 主要分爲兩大主流:
sh:
burne shell (sh)
burne again shell (bash)
csh:
c shell (csh)
tc shell (tcsh)
korn shell (ksh)
大部份的 linux 系統的預設 shell 都是 bash ,其緣由大體以下兩點:
* 自由軟件
* 功能強大
bash 是 gnu project 最成功的產品之一,自推出以來深受廣大 Unix 用戶喜好,且也逐漸成爲很多組織的系統標準。
------------------------------------------------------------------
2) shell prompt(PS1) 與 Carriage Return(CR) 的關係?
當你成功登陸進一個文字界面以後,大部份情形下,你會在熒幕上看到一個不斷閃爍的方塊或底線(視不一樣版本而別),
咱們稱之爲*遊標*(coursor)。遊標的做用就是告訴你接下來你從鍵盤輸入的按鍵所插入的位置,且每輸如一鍵遊標便向右邊移動一個格子,若連續輸入太多的話,則自動接在下一行輸入。
假如你剛完成登陸還沒輸入任何按鍵以前,你所看到的遊標所在位置的同一行的左邊部份,咱們稱之爲*提示符號*(prompt)。提示符號的格式或因不一樣系統版本而各有不一樣,在 linux 上,只需留意最接近遊標的一個可見的提示符號,一般是以下二者之一:
$:給通常使用者帳號使用
#:給 root (管理員)帳號使用
事實上,shell prompt 的意思很簡單:
* 是 shell 告訴使用者:您如今能夠輸入命令行了。咱們能夠說,使用者只有在獲得 shell prompt 才能打命令行,
而 cursor 是指示鍵盤在命令行所輸入的位置,使用者每輸入一個鍵,cursor 就日後移動一格,直到碰到命令行讀進 CR(Carriage Return,由 Enter 鍵產生)字符爲止。CR 的意思也很簡單:
* 是使用者告訴 shell:老兄你能夠執行個人命令行了。
嚴格來講:
* 所謂的命令行,就是在 shell prompt 與 CR 字符之間所輸入的文字。 (思考:爲什麼咱們這裏堅持使用 CR 字符而不說 Enter 鍵呢?答案在後面的學習中揭曉。)
不一樣的命令可接受的命令行格式或有不一樣,通常狀況下,一個標準的命令行格式爲以下所列:
command-name options argument
若從技術細節來看,shell 會依據 IFS(Internal Field Seperator) 將 command line 所輸入的文字給拆解爲"字段"(word)。
而後再針對特殊字符(meta)先做處理,最後再重組整行 command line 。(注意:請務必理解上兩句話的意思,咱們往後的學習中會常回到這裏思考。)
其中的 IFS 是 shell 預設使用的字段分隔符,能夠由一個及多個以下按鍵組成:
* 空格鍵(White Space)
* 表格鍵(Tab)
* 回車鍵(Enter)
系統可接受的命令名稱(command-name)能夠從以下途徑得到:
* 明確路徑所指定的外部命令
* 命令別名(alias)
* 自定功能(function)
* shell 內建命令(built-in)
* $PATH 之下的外部命令
每個命令行均必需含用命令名稱,這是不能缺乏的。
---------------------------------------------------------------------------------------------
3) 別人 echo、你也 echo ,是問 echo 知多少?
承接上一章所介紹的 command line ,這裏咱們用 echo 這個命令加以進一步說明。溫習---標準的 command line 包含三個部件:* command_name option argument
echo 是一個很是簡單、直接的 linux 命令:* 將 argument 送出至標準輸出(STDOUT),一般就是在監視器(monitor)上輸出。爲了更好理解,不如先讓咱們先跑一下 echo 命令好了:
$ echo
$
你會發現只有一個空白行,而後又回到 shell prompt 上了。這是由於 echo 在預設上,在顯示完 argument 以後,還會送出一個換行符號(new-line charactor)。可是上面的 command 並沒任何的 argument ,那結果就只剩一個換行符號了...
若你要取消這個換行符號,可利用 echo 的 -n option :
$ echo -n
$
不妨讓咱們回到 command line 的概念上來討論上例的 echo 命令好了:
* command line 只有 command_name(echo) 及 option(-n),並無任何 argument 。
要想看看 echo 的 argument ,那還不簡單﹗接下來,你可試試以下的輸入:
CODE:[Copy to clipboard]$ echo first line
first line
$ echo -n first line
first line $
於上兩個 echo 命令中,你會發現 argument 的部份顯示在你的熒幕,而換行符號則視 -n option 的有無而別。
很明顯的,第二個 echo 因爲換行符號被取消了,接下來的 shell prompt 就接在輸出結果同一行了... ^_^
事實上,echo 除了 -n options 以外,經常使用選項還有:
-e :啓用反斜線控制字符的轉換(參考下表)
-E:關閉反斜線控制字符的轉換(預設如此)
-n :取消行末之換行符號(與 -e 選項下的 /c 字符贊成)
關於 echo 命令所支持的反斜線控制字符以下表:
/a:ALERT / BELL (從系統喇叭送出鈴聲)
/b:BACKSPACE ,也就是向左刪除鍵
/c:取消行末之換行符號
/E:ESCAPE,跳脫鍵
/f:FORMFEED,換頁字符
/n:NEWLINE,換行字符
/r:RETURN,回車鍵
/t:TAB,表格跳位鍵
/v:VERTICAL TAB,垂直表格跳位鍵
/n:ASCII 八進位編碼(以 x 開首爲十六進制)
//:反斜線自己
(表格數據來自 O'Reilly 出版社之 Learning the Bash Shell, 2nd Ed.)
或許,咱們能夠透過實例來了解 echo 的選項及控制字符:
例一:
CODE:[Copy to clipboard]$ echo -e "a/tb/tc/nd/te/tf"
a b c
d e f
上例運用 /t 來區隔 abc 還有 def ,及用 /n 將 def 換至下一行。
例二:
CODE:[Copy to clipboard]$ echo -e "/141/011/142/011/143/012/144/011/145/011/146"
a b c
d e f
與例一的結果同樣,只是使用 ASCII 八進位編碼。
例三:
CODE:[Copy to clipboard]$ echo -e "/x61/x09/x62/x09/x63/x0a/x64/x09/x65/x09/x66"
a b c
d e f
與例二差很少,只是此次換用 ASCII 十六進制編碼。
例四:
CODE:[Copy to clipboard]$ echo -ne "a/tb/tc/nd/te/bf/a"
a b c
d f $
由於 e 字母后面是刪除鍵(/b),所以輸出結果就沒有 e 了。
在結束時聽到一聲鈴向,那是 /a 的傑做﹗
因爲同時使用了 -n 選項,所以 shell prompt 緊接在第二行以後。
若你不用 -n 的話,那你在 /a 後再加個 /c ,也是一樣的效果。
事實上,在往後的 shell 操做及 shell script 設計上,echo 命令是最常被使用的命令之一。
比方說,用 echo 來檢查變量值:
CODE:[Copy to clipboard]$ A=B
$ echo $A
B
$ echo $?
0
(注:關於變量概念,咱們留到下兩章纔跟你們說明。)
好了,更多的關於 command line 的格式,以及 echo 命令的選項,
就請您自行多加練習、運用了...
-------------------------------------------------------------------------------------------------------------
4) " "(雙引號) 與 ' '(單引號)差在哪?
仍是回到咱們的 command line 來吧...
通過前面兩章的學習,應該很清楚當你在 shell prompt 後面敲打鍵盤、直到按下 Enter 的時候,
你輸入的文字就是 command line 了,而後 shell 纔會以行程的方式執行你所交給它的命令。
可是,你又可知道:你在 command line 輸入的每個文字,對 shell 來講,是有類別之分的呢?
簡單而言(我不敢說這是精確的定議,注一),command line 的每個 charactor ,分爲以下兩種:
* literal:也就是普通純文字,對 shell 來講沒特殊功能。
* meta:對 shell 來講,具備特定功能的特殊保留字符。
(注一:關於 bash shell 在處理 command line 時的順序說明,
請參考 O'Reilly 出版社之 Learning the Bash Shell, 2nd Edition,第 177 - 180 頁的說明,
尤爲是 178 頁的流程圖 Figure 7-1 ... )
Literal 沒甚麼好談的,凡舉 abcd、123456 這些"文字"都是 literal ... (easy?)
但 meta 卻常使咱們困惑..... (confused?)
事實上,前兩章咱們在 command line 中已碰到兩個機乎每次都會碰到的 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 列表中的命令
....
假如咱們須要在 command line 中將這些保留字符的功能關閉的話,就須要 quoting 處理了。
在 bash 中,經常使用的 quoting 有以下三種方法:
* hard quote:' ' (單引號),凡在 hard quote 中的全部 meta 均被關閉。
* soft quote: " " (雙引號),在 soft quoe 中大部份 meta 都會被關閉,但某些則保留(如 $ )。(注二)
* escape : / (反斜線),只有緊接在 escape (跳脫字符)以後的單一 meta 才被關閉。
( 注二:在 soft quote 中被豁免的具體 meta 清單,我不徹底知道,
有待你們補充,或透過實做來發現及理解。 )
下面的例子將有助於咱們對 quoting 的瞭解:
CODE:[Copy to clipboard] $ A=B C # 空格鍵未被關掉,做爲 IFS 處理。
$ C: command not found.
$ echo $A
$ A="B C" # 空格鍵已被關掉,僅做爲空格鍵處理。
$ echo $A
B C
在第一次設定 A 變量時,因爲空格鍵沒被關閉,command line 將被解讀爲:
* A=B 而後碰到<IFS>;,再執行 C 命令
在第二次設定 A 變量時,因爲空格鍵被置於 soft quote 中,所以被關閉,再也不做爲 IFS :
* A=B<space>;C
事實上,空格鍵不管在 soft quote 仍是在 hard quote 中,均會被關閉。Enter 鍵亦然:
CODE:[Copy to clipboard] $ A='B
>; C
>; '
$ echo "$A"
B
C
在上例中,因爲 <enter>; 被置於 hard quote 當中,所以再也不做爲 CR 字符來處理。
這裏的 <enter>; 單純只是一個斷行符號(new-line)而已,因爲 command line 並沒獲得 CR 字符,
所以進入第二個 shell prompt (PS2,以 >; 符號表示),command line 並不會結束,
直到第三行,咱們輸入的 <enter>; 並不在 hard quote 裏面,所以並沒被關閉,
此時,command line 碰到 CR 字符,因而結束、交給 shell 來處理。
上例的 <enter>; 要是被置於 soft quote 中的話, CR 也會一樣被關閉:
CODE:[Copy to clipboard] $ A="B
>; C
>; "
$ echo $A
B C
然而,因爲 echo $A 時的變量沒至於 soft quote 中,所以當變量替換完成後並做命令行重組時,<enter>; 會被解釋爲 IFS ,而不是解釋爲 New Line 字符。
一樣的,用 escape 亦可關閉 CR 字符:
CODE:[Copy to clipboard] $ A=B/
>; C/
>;
$ echo $A
BC
上例中,第一個 <enter>; 跟第二個 <enter>; 均被 escape 字符關閉了,所以也不做爲 CR 來處理,
但第三個 <enter>; 因爲沒被跳脫,所以做爲 CR 結束 command line 。
但因爲 <enter>; 鍵自己在 shell meta 中的特殊性,在 / 跳脫後面,僅僅取消其 CR 功能,而不會保留其 IFS 功能。
您或許發現光是一個 <enter>; 鍵所產生的字符就有多是以下這些可能:
CR
IFS
NL(New Line)
FF(Form Feed)
NULL
...
至於甚麼時候會解釋爲甚麼字符,這個我就沒去深挖了,或是留給讀者諸君自行慢慢摸索了... ^_^
至於 soft quote 跟 hard quote 的不一樣,主要是對於某些 meta 的關閉與否,以 $ 來做說明:
CODE:[Copy to clipboard] $ A=B/ C
$ echo "$A"
B C
$ echo '$A'
$A
在第一個 echo 命令行中,$ 被置於 soft quote 中,將不被關閉,所以繼續處理變量替換,
所以 echo 將 A 的變量值輸出到熒幕,也就獲得 "B C" 的結果。
在第二個 echo 命令行中,$ 被置於 hard quote 中,則被關閉,所以 $ 只是一個 $ 符號,
並不會用來做變量替換處理,所以結果是 $ 符號後面接一個 A 字母:$A 。
--------------------------------------
練習與思考:以下結果爲什麼不一樣?
CODE:[Copy to clipboard] $ A=B/ C
$ echo '"$A"' # 最外面的是單引號
"$A"
$ echo "'$A'" # 最外面的是雙引號
'B C'
(提示:單引號及雙引號,在 quoting 中均被關?#93;了。)
--------------------------------------
在 CU 的 shell 版裏,我發現有不少初學者的問題,都與 quoting 理解的有關。
比方說,若咱們在 awk 或 sed 的命令參數中調用以前設定的一些變量時,常會問及爲什麼不能的問題。
要解決這些問題,關鍵點就是:
* 區分出 shell meta 與 command meta
前面咱們提到的那些 meta ,都是在 command line 中有特殊用途的,
比方說 { } 是將其內一系列 command line 置於不具名的函式中執行(可簡單視爲 command block ),
可是,awk 卻須要用 { } 來區分出 awk 的命令區段(BEGIN, MAIN, END)。
若你在 command line 中如此輸入:
CODE:[Copy to clipboard]$ awk {print $0} 1.txt
因爲 { } 在 shell 中並沒關閉,那 shell 就將 {print $0} 視爲 command block ,
但同時又沒有" ; "符號做命令區隔,所以就出現 awk 的語法錯誤結果。
要解決之,可用 hard quote :
CODE:[Copy to clipboard]$ awk '{print $0}' 1.txt
上面的 hard quote 應好理解,就是將本來的 {、<space>;、$(注三)、} 這幾個 shell meta 關閉,
避免掉在 shell 中遭處處理,而完整的成爲 awk 參數中的 command meta 。
( 注三:而其中的 $0 是 awk 內建的 field number ,而非 awk 的變量,
awk 自身的變量無需使用 $ 。)
要是理解了 hard quote 的功能,再來理解 soft quote 與 escape 就不難:
CODE:[Copy to clipboard]awk "{print /$0}" 1.txt
awk /{print/ /$0/} 1.txt
然而,若你要改變 awk 的 $0 的 0 值是從另外一個 shell 變量讀進呢?
比方說:已有變量 $A 的值是 0 ,那如何在 command line 中解決 awk 的 $$A 呢?
你能夠很直接否認掉 hard quoe 的方案:
CODE:[Copy to clipboard]$ awk '{print $$A}' 1.txt
那是由於 $A 的 $ 在 hard quote 中是不能替換變量的。
聰明的讀者(如你!),通過本章學習,我想,應該能夠解釋爲什麼咱們可使用以下操做了吧:
CODE:[Copy to clipboard]A=0
awk "{print /$$A}" 1.txt
awk /{print/ /$$A/} 1.txt
awk '{print $'$A'}' 1.txt
awk '{print $'"$A"'}' 1.txt # 注:"$A" 包在 soft quote 中
或許,你能舉出更多的方案呢.... ^_^
--------------------------------------
練習與思考:請運用本章學到的知識分析以下兩串討論:
[url]http://bbs.chinaunix.net/forum/viewtopic.php?t=207178[/url]
[url]http://bbs.chinaunix.net/forum/viewtopic.php?t=216729[/url]
-----------------------------------------------------------------------------------------------------------------------
5) var=value?export 先後差在哪?
此次讓咱們暫時丟開 command line ,先來了解一下 bash 變量(variable)吧...
所謂的變量,就是就是利用一個特定的"名稱"(name)來存取一段能夠變化的"值"(value)。
*設定(set)*
在 bash 中,你能夠用 "=" 來設定或從新定義變量的內容:
name=value
在設定變量的時侯,得遵照以下規則:
* 等號左右兩邊不能使用區隔符號(IFS),也應避免使用 shell 的保留字符(meta charactor)。
* 變量名稱不能使用 $ 符號。
* 變量名稱的第一個字母不能是數字(number)。
* 變量名稱長度不可超過 256 個字母。
* 變量名稱及變量值之大小寫是有區別的(case sensitive)。
以下是一些變量設定時常見的錯誤:
A= B :不能有 IFS
1A=B :不能以數字開頭
$A=B :名稱不能有 $
a=B :這跟 a=b 是不一樣的
以下則是能夠接受的設定:
A=" B" :IFS 被關閉了 (請參考前面的 quoting 章節)
A1=B :並不是以數字開頭
A=$B :$ 可用在變量值內
This_Is_A_Long_Name=b :可用 _ 鏈接較長的名稱或值,且大小寫有別。
*變量替換(substitution)*
Shell 之因此強大,其中的一個因素是它能夠在命令行中對變量做替換(substitution)處理。
在命令行中使用者可使用 $ 符號加上變量名稱(除了在用 = 號定義變量名稱以外),
將變量值給替換出來,而後再從新組建命令行。
比方:
CODE:[Copy to clipboard] $ A=ls
$ B=la
$ C=/tmp
$ $A -$B $C
(注意:以上命令行的第一個 $ 是 shell prompt ,並不在命令行以內。)
必需強調的是,咱們所提的變量替換,只發生在 command line 上面。(是的,讓咱們再回到 command line 吧﹗)
仔細分析最後那行 command line ,不難發如今被執行以前(在輸入 CR 字符以前),
$ 符號會對每個變量做替換處理(將變量值替換出來再重組命令行),最後會得出以下命令行:
CODE:[Copy to clipboard] ls -la /tmp
還記得第二章我請你們"務必理解"的那兩句嗎?若你忘了,那我這裏再重貼一遍:
QUOTE:
若從技術細節來看,shell 會依據 IFS(Internal Field Seperator) 將 command line 所輸入的文字給拆解爲"字段"(word)。
而後再針對特殊字符(meta)先做處理,最後再重組整行 command line 。
這裏的 $ 就是 command line 中最經典的 meta 之一了,就是做變量替換的﹗
在平常的 shell 操做中,咱們常會使用 echo 命令來查看特定變量的值,例如:
CODE:[Copy to clipboard] $ echo $A -$B $C
咱們已學過, echo 命令只單純將其 argument 送至"標準輸出"(STDOUT,一般是咱們的熒幕)。
因此上面的命令會在熒幕上獲得以下結果:
CODE:[Copy to clipboard] ls -la /tmp
這是因爲 echo 命令在執行時,會先將 $A(ls)、$B(la)、跟 $C(/tmp) 給替換出來的結果。
利用 shell 對變量的替換處理能力,咱們在設定變量時就更爲靈活了:
A=B
B=$A
這樣,B 的變量值就可繼承 A 變量"當時"的變量值了。
不過,不要以"數學羅輯"來套用變量的設定,比方說:
A=B
B=C
這樣並不會讓 A 的變量值變成 C 。再如:
A=B
B=$A
A=C
一樣也不會讓 B 的值換成 C 。
上面是單純定義了兩個不一樣名稱的變量:A 與 B ,它們的值分別是 B 與 C 。
若變量被重複定義的話,則原有舊值將被新值所取代。(這不正是"可變的量"嗎? ^_^)
當咱們在設定變量的時侯,請記着這點:
* 用一個名稱儲存一個數值
僅此而已。
此外,咱們也可利用命令行的變量替換能力來"擴充"(append)變量值:
A=B:C:D
A=$A:E
這樣,第一行咱們設定 A 的值爲 "B:C:D",而後,第二行再將值擴充爲 "A:B:C:E" 。
上面的擴充範例,咱們使用區隔符號( : )來達到擴充目的,
要是沒有區隔符號的話,以下是有問題的:
A=BCD
A=$AE
由於第二次是將 A 的值繼承 $AE 的提換結果,而非 $A 再加 E ﹗
要解決此問題,咱們可用更嚴謹的替換處理:
A=BCD
A=${A}E
上例中,咱們使用 {} 將變量名稱的範圍給明肯定義出來,
如此一來,咱們就能夠將 A 的變量值從 BCD 給擴充爲 BCDE 。
(提示:關於 ${name} 事實上還可作到更多的變量處理能力,這些均屬於比較進階的變量處理,
現階段暫時不介紹了,請你們自行參考數據。如 CU 的貼子:
[url]http://www.chinaunix.net/forum/viewtopic.php?t=201843[/url]
)
* export *
嚴格來講,咱們在當前 shell 中所定義的變量,均屬於"本地變量"(local variable),
只有通過 export 命令的"輸出"處理,才能成爲環境變量(environment variable):
CODE:[Copy to clipboard] $ A=B
$ export A
或:
CODE:[Copy to clipboard] $ export A=B
通過 export 輸出處理以後,變量 A 就能成爲一個環境變量供其後的命令使用。
在使用 export 的時侯,請別忘記 shell 在命令行對變量的"替換"(substitution)處理,
比方說:
CODE:[Copy to clipboard] $ A=B
$ B=C
$ export $A
上面的命令並未將 A 輸出爲環境變量,而是將 B 做輸出,
這是由於在這個命令行中,$A 會首先被提換出 B 而後再"塞回"做 export 的參數。
要理解這個 export ,事實上須要從 process 的角度來理解才能透徹。
我將於下一章爲你們說明 process 的觀念,敬請留意。
*取消變量*
要取消一個變量,在 bash 中可以使用 unset 命令來處理:
CODE:[Copy to clipboard] unset A
與 export 同樣,unset 命令行也一樣會做變量替換(這其實就是 shell 的功能之一),
所以:
CODE:[Copy to clipboard] $ A=B
$ B=C
$ unset $A
事實上所取消的變量是 B 而不是 A 。
此外,變量一旦通過 unset 取消以後,其結果是將整個變量拿掉,而不只是取消其變量值。
以下兩行實際上是很不同的:
CODE:[Copy to clipboard] $ A=
$ unset A
第一行只是將變量 A 設定爲"空值"(null value),但第二行則讓變量 A 不在存在。
雖然用眼睛來看,這兩種變量狀態在以下命令結果中都是同樣的:
CODE:[Copy to clipboard] $ A=
$ echo $A
$ unset A
$ echo $A
請學員務必能識別 null value 與 unset 的本質區別,這在一些進階的變量處理上是很嚴格的。
比方說:
CODE:[Copy to clipboard] $ str= # 設爲 null
$ var=${str=expr} # 定義 var
$ echo $var
$ echo $str
$ unset str # 取消
$ var=${str=expr} # 定義 var
$ echo $var
expr
$ echo $str
expr
聰明的讀者(yes, you!),稍加思考的話,
應該不難發現爲什麼一樣的 var=${str=expr} 在 null 與 unset 之下的不一樣吧?
若你看不出來,那多是以下緣由之一:
a. 你太笨了
b. 不瞭解 var=${str=expr} 這個進階處理
c. 對本篇說明還沒來得及消化吸取
e. 我講得很差
不知,你選哪一個呢?.... ^_^
----------------------------------------------------------------------------------------------------- php
10) && 與 || 差在哪?
-----------
轉自http://blog.csdn.net/freexploit/article/details/626660express |