Linux系統程式設計(13)——Shell的基本語法

尹成發表於2014-07-25

 

按照慣例,Shell變數由全大寫字母加下劃線組成,有兩種型別的Shell變數:環境變數和本地變數。

 

環境變數:

環境變數可以從父程式傳給子程式,因此Shell程式的環境變數可以從當前Shell程式傳給fork出來的子程式。用printenv命令可以顯示當前Shell程式的環境變數。

 

本地變數

只存在於當前Shell程式,用set命令可以顯示當前Shell程式中定義的所有變數(包括本地變數和環境變數)和函式。

 

環境變數是任何程式都有的概念,而本地變數是Shell特有的概念。在Shell中,環境變數和本地變數的定義和用法相似。

 

定義變數:

 

定義變數時,變數名不加美元符號($),如:

variableName="value"


注意,變數名和等號之間不能有空格,這可能和你熟悉的所有程式語言都不一樣。同時,變數名的命名須遵循如下規則:

首個字元必須為字母(a-z,A-Z)。

中間不能有空格,可以使用下劃線(_)。

不能使用標點符號。

不能使用bash裡的關鍵字(可用help命令檢視保留關鍵字)。

使用變數

 

使用一個定義過的變數,只要在變數名前面加美元符號($)即可,如:

your_name="tom"
echo $your_name
echo ${your_name}


變數名外面的花括號是可選的,加不加都行,加花括號是為了幫助直譯器識別變數的邊界,比如下面這種情況:

for skill in Ada Coffe Action Java
do
   echo "I am good at ${skill}Script"
done


如果不給skill變數加花括號,寫成echo "I am good at $skillScript",直譯器就會把$skillScript當成一個變數(其值為空),程式碼執行結果就不是我們期望的樣子了。

 

推薦給所有變數加上花括號,這是個好的程式設計習慣。

重新定義變數

 

已定義的變數,可以被重新定義,如:

your_name="Tom"
echo $your_name
your_name="Alibaba"
echo $your_name


這樣寫是合法的,但注意,第二次賦值的時候不能寫$your_name="alibaba",使用變數的時候才加美元符($)。

 

 檔名代換:* ? []

這些用於匹配的字元稱為萬用字元,具體如下:

 

* 匹配0個或多個任意字元

? 匹配一個任意字元

[若干字元] 匹配方括號中任意一個字元的一次出現

 

 

$ ls /dev/ttyS*
$ ls ch0?.doc
$ ls ch0[0-2].txt
$ ls ch[012][0-9].txt

注意,Globbing所匹配的檔名是由Shell展開的,也就是說在引數還沒傳給程式之前已經展開了,比如上述ls ch0[012].doc命令,如果當前目錄下有ch00.doc和ch02.doc,則傳給ls命令的引數實際上是這兩個檔名,而不是一個匹配字串。

 

命令代換:

`或 $()。

由反引號括起來的也是一條命令,Shell先執行該命令,然後將輸出結果立刻代換到當前命令列中。例如定義一個變數存放date命令的輸出:

 

$ DATE=`date`
$ echo $DATE

命令代換也可以用$()表示:

$ DATE=$(date


算術代換:

$(())用於算術計算,$(())中的Shell變數取值將轉換成整數,例如:

 

$ VAR=45
$ echo $(($VAR+3))


$(())中只能用+-*/和()運算子,並且只能做整數運算。

 

轉義字元

和C語言類似,\在Shell中被用作轉義字元,用於去除緊跟其後的單個字元的特殊意義(回車除外),換句話說,緊跟其後的字元取字面值。例如:

 

$ echo $SHELL
/bin/bash
$ echo \$SHELL
$SHELL
$ echo \\


\比如建立一個檔名為“$ $”的檔案可以這樣:

 

$ touch \$\ \$還有一個字元雖然不具有特殊含義,但是要用它做檔名也很麻煩,就是-號。如果要建立一個檔名以-號開頭的檔案,這樣是不行的:

 

$ touch -hello
touch: invalid option -- h
Try `touch --help' for more information.


即使加上\轉義也還是報錯:

 

$ touch \-hello
touch: invalid option -- h
Try `touch --help' for more information.


因為各種UNIX命令都把-號開頭的命令列引數當作命令的選項,而不會當作檔名。如果非要處理以-號開頭的檔名,可以有兩種辦法:

 

$ touch ./-hello


或者

$ touch -- -hello


\還有一種用法,在\後敲回車表示續行,Shell並不會立刻執行命令,而是把游標移到下一行,給出一個續行提示符>,等待使用者繼續輸入,最後把所有的續行接到一起當作一個命令執行。例如ls -l命令的輸出:

 

$ ls \
> -l


 

單引號

和C語言不一樣,Shell指令碼中的單引號和雙引號一樣都是字串的界定符(雙引號下一節介紹),而不是字元的界定符。單引號用於保持引號內所有字元的字面值,即使引號內的\和回車也不例外,但是字串中不能出現單引號。如果引號沒有配對就輸入回車,Shell會給出續行提示符,要求使用者把引號配上對。例如:

 

$ echo '$SHELL'
$SHELL
$ echo 'ABC\(回車)
> DE'(再按一次回車結束命令)
ABC\
DE

 

雙引號

雙引號用於保持引號內所有字元的字面值(回車也不例外),但以下情況除外:

 

反引號仍表示命令替換

\$表示$的字面值

\`表示`的字面值

\"表示"的字面值

\\表示\的字面值

 

除以上情況之外,在其它字元前面的\無特殊含義,只表示字面值

 

$ echo "$SHELL"
/bin/bash
$ echo "`date`"
Sun Apr 20 11:22:06 CEST 2003
$ echo "I'd say: \"Go forit\""
I'd say: "Go for it"
$ echo "\"(回車)
>"(再按一次回車結束命令)
"
 
$ echo "\\"
\


 

相關文章