最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

shell編程——基本語(yǔ)法

2020-10-20 17:12 作者:Iammyself001  | 我要投稿

shell歷史

Shell的作用是解釋執(zhí)行用戶的命令,用戶輸入一條命令,Shell就解釋執(zhí)行一條,這種方式稱為交互式(Interactive),Shell還有一種執(zhí)行命令的方式稱為批處理(Batch),用戶事先寫(xiě)一個(gè)Shell腳本(Script),其中有很多條命令,讓Shell一次把這些命令執(zhí)行完,而不必一條一條地敲命令。Shell腳本和編程語(yǔ)言很相似,也有變量和流程控制語(yǔ)句,但Shell腳本是解釋執(zhí)行的,不需要編譯,Shell程序從腳本中一行一行讀取并執(zhí)行這些命令,相當(dāng)于一個(gè)用戶把腳本中的命令一行一行敲到Shell提示符下執(zhí)行。

由于歷史原因,UNIX系統(tǒng)上有很多種Shell:

1.sh(Bourne Shell):由Steve Bourne開(kāi)發(fā),各種UNIX系統(tǒng)都配有sh。

2.csh(C Shell):由Bill Joy開(kāi)發(fā),隨BSD UNIX發(fā)布,它的流程控制語(yǔ)句很像C語(yǔ)言,支持很多Bourne Shell所不支持的功能:作業(yè)控制,命令歷史,命令行編輯。

3.ksh(Korn Shell):由David Korn開(kāi)發(fā),向后兼容sh的功能,并且添加了csh引入的新功能,是目前很多UNIX系統(tǒng)標(biāo)準(zhǔn)配置的Shell,在這些系統(tǒng)上/bin/sh往往是指向/bin/ksh的符號(hào)鏈接。

4.tcsh(TENEX C Shell):是csh的增強(qiáng)版本,引入了命令補(bǔ)全等功能,在FreeBSD、Mac OS X等系統(tǒng)上替代了csh。

5.bash(Bourne Again Shell):由GNU開(kāi)發(fā)的Shell,主要目標(biāo)是與POSIX標(biāo)準(zhǔn)保持一致,同時(shí)兼顧對(duì)sh的兼容,bash從csh和ksh借鑒了很多功能,是各種Linux發(fā)行版標(biāo)準(zhǔn)配置的Shell,在Linux系統(tǒng)上/bin/sh往往是指向/bin/bash的符號(hào)鏈接。雖然如此,bash和sh還是有很多不同的,一方面,bash擴(kuò)展了一些命令和參數(shù),另一方面,bash并不完全和sh兼容,有些行為并不一致,所以bash需要模擬sh的行為:當(dāng)我們通過(guò)sh這個(gè)程序名啟動(dòng)bash時(shí),bash可以假裝自己是sh,不認(rèn)擴(kuò)展的命令,并且行為與sh保持一致。

6.zsh 的命令補(bǔ)全功能非常強(qiáng)大,可以補(bǔ)齊路徑,補(bǔ)齊命令,補(bǔ)齊參數(shù)等。

vim /etc/passwd 其中最后一列顯示了用戶對(duì)應(yīng)的shell類型 root:x:0:0:root:/root:/bin/bash nobody:x:65534:65534:nobody:/nonexistent:/bin/sh syslog:x:101:103::/home/syslog:/bin/false itcast:x:1000:1000:itcast,,,:/home/itcast:/bin/bash ftp:x:115:125:ftp daemon,,,:/srv/ftp:/bin/false

用戶在命令行輸入命令后,一般情況下Shell會(huì)fork并exec該命令,但是Shell的內(nèi)建命令例外,執(zhí)行內(nèi)建命令相當(dāng)于調(diào)用Shell進(jìn)程中的一個(gè)函數(shù),并不創(chuàng)建新的進(jìn)程。以前學(xué)過(guò)的cd、alias、umask、exit等命令即是內(nèi)建命令,凡是用which命令查不到程序文件所在位置的命令都是內(nèi)建命令,內(nèi)建命令沒(méi)有單獨(dú)的man手冊(cè),要在man手冊(cè)中查看內(nèi)建命令,應(yīng)該

$ man bash-builtins

如export、shift、if、eval、[、for、while等等。內(nèi)建命令雖然不創(chuàng)建新的進(jìn)程,但也會(huì)有Exit Status,通常也用0表示成功非零表示失敗,雖然內(nèi)建命令不創(chuàng)建新的進(jìn)程,但執(zhí)行結(jié)束后也會(huì)有一個(gè)狀態(tài)碼,也可以用特殊變量$?讀出。

執(zhí)行腳本

編寫(xiě)一個(gè)簡(jiǎn)單的腳本test.sh:

#! /bin/sh

cd ..?

ls

Shell腳本中用#表示注釋,相當(dāng)于C語(yǔ)言的//注釋。但如果#位于第一行開(kāi)頭,并且是#!(稱為Shebang)則例外,它表示該腳本使用后面指定的解釋器/bin/sh解釋執(zhí)行。如果把這個(gè)腳本文件加上可執(zhí)行權(quán)限然后執(zhí)行:

chmod a+x test.sh?

./test.sh

Shell會(huì)fork一個(gè)子進(jìn)程并調(diào)用exec執(zhí)行./test.sh這個(gè)程序,exec系統(tǒng)調(diào)用應(yīng)該把子進(jìn)程的代碼段替換成./test.sh程序的代碼段,并從它的_start開(kāi)始執(zhí)行。然而test.sh是個(gè)文本文件,根本沒(méi)有代碼段和_start函數(shù),怎么辦呢?其實(shí)exec還有另外一種機(jī)制,如果要執(zhí)行的是一個(gè)文本文件,并且第一行用Shebang指定了解釋器,則用解釋器程序的代碼段替換當(dāng)前進(jìn)程,并且從解釋器的_start開(kāi)始執(zhí)行,而這個(gè)文本文件被當(dāng)作命令行參數(shù)傳給解釋器。因此,執(zhí)行上述腳本相當(dāng)于執(zhí)行程序

$ /bin/sh ./test.sh

以這種方式執(zhí)行不需要test.sh文件具有可執(zhí)行權(quán)限。

如果將命令行下輸入的命令用()括號(hào)括起來(lái),那么也會(huì)fork出一個(gè)子Shell執(zhí)行小括號(hào)中的命令,一行中可以輸入由分號(hào);隔開(kāi)的多個(gè)命令,比如:

$ (cd ..;ls -l)

和上面兩種方法執(zhí)行Shell腳本的效果是相同的,cd ..命令改變的是子Shell的PWD,而不會(huì)影響到交互式Shell。然而命令

$ cd ..;ls -l

則有不同的效果,cd ..命令是直接在交互式Shell下執(zhí)行的,改變交互式Shell的PWD,然而這種方式相當(dāng)于這樣執(zhí)行Shell腳本:

$ source ./test.sh

或者

$ . ./test.sh

source或者.命令是Shell的內(nèi)建命令,這種方式也不會(huì)創(chuàng)建子Shell,而是直接在交互式Shell下逐行執(zhí)行腳本中的命令。

基本語(yǔ)法

變量

按照慣例,Shell變量由全大寫(xiě)字母加下劃線組成,有兩種類型的Shell變量:

1.環(huán)境變量

環(huán)境變量可以從父進(jìn)程傳給子進(jìn)程,因此Shell進(jìn)程的環(huán)境變量可以從當(dāng)前Shell進(jìn)程傳給fork出來(lái)的子進(jìn)程。用printenv命令可以顯示當(dāng)前Shell進(jìn)程的環(huán)境變量。

2.本地變量

只存在于當(dāng)前Shell進(jìn)程,用set命令可以顯示當(dāng)前Shell進(jìn)程中定義的所有變量(包括本地變量和環(huán)境變量)和函數(shù)。

環(huán)境變量是任何進(jìn)程都有的概念,而本地變量是Shell特有的概念。在Shell中,環(huán)境變量和本地變量的定義和用法相似。在Shell中定義或賦值一個(gè)變量:

itcast$ VARNAME=value

注意等號(hào)兩邊都不能有空格,否則會(huì)被Shell解釋成命令和命令行參數(shù)。

一個(gè)變量定義后僅存在于當(dāng)前Shell進(jìn)程,它是本地變量,用export命令可以把本地變量導(dǎo)出為環(huán)境變量,定義和導(dǎo)出環(huán)境變量通常可以一步完成:

itcast$ export VARNAME=value

也可以分兩步完成:

itcast$ VARNAME=value?

itcast$ export VARNAME

用unset命令可以刪除已定義的環(huán)境變量或本地變量。

itcast$ unset VARNAME

如果一個(gè)變量叫做VARNAME,用${VARNAME}可以表示它的值,在不引起歧義的情況下也可以用$VARNAME表示它的值。通過(guò)以下例子比較這兩種表示法的不同:

itcast$ echo $SHELL

注意,在定義變量時(shí)不用$,取變量值時(shí)要用$。和C語(yǔ)言不同的是,Shell變量不需要明確定義類型,事實(shí)上Shell變量的值都是字符串,比如我們定義VAR=45,其實(shí)VAR的值是字符串45而非整數(shù)。Shell變量不需要先定義后使用,如果對(duì)一個(gè)沒(méi)有定義的變量取值,則值為空字符串。

文件名代換(Globbing):* ? []

這些用于匹配的字符稱為通配符(Wildcard),具體如下:

通配符?

* ? 匹配0個(gè)或多個(gè)任意字符

? ? 匹配一個(gè)任意字符?

[若干字符] ?匹配方括號(hào)中任意一個(gè)字符的一次出現(xiàn)?

$ ls /dev/ttyS*?

$ ls ch0?.doc?

$ ls ch0[0-2].doc?

$ ls ch[012] ? [0-9].doc

注意,Globbing所匹配的文件名是由Shell展開(kāi)的,也就是說(shuō)在參數(shù)還沒(méi)傳給程序之前已經(jīng)展開(kāi)了,比如上述ls ch0[012].doc命令,如果當(dāng)前目錄下有ch00.doc和ch02.doc,則傳給ls命令的參數(shù)實(shí)際上是這兩個(gè)文件名,而不是一個(gè)匹配字符串。

命令代換:`或 $()

由'`'反引號(hào)括起來(lái)的也是一條命令,Shell先執(zhí)行該命令,然后將輸出結(jié)果立刻代換到當(dāng)前命令行中。例如定義一個(gè)變量存放date命令的輸出:

itcast$ DATE=`date`?

itcast$ echo $DATE

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

itcast$ DATE=$(date)

算術(shù)代換:$(())

用于算術(shù)計(jì)算,$(())中的Shell變量取值將轉(zhuǎn)換成整數(shù),同樣含義的$[]等價(jià)例如:

itcast$ VAR=45?

itcast$ echo $(($VAR+3))?

$(())中只能用+-*/和()運(yùn)算符,并且只能做整數(shù)運(yùn)算。

$[base#n],其中base表示進(jìn)制,n按照base進(jìn)制解釋,后面再有運(yùn)算數(shù),按十進(jìn)制解釋。

echo $[2#10+11]?

echo $[8#10+11]?

echo $[10#10+11]

轉(zhuǎn)義字符\

和C語(yǔ)言類似,\在Shell中被用作轉(zhuǎn)義字符,用于去除緊跟其后的單個(gè)字符的特殊意義(回車除外),換句話說(shuō),緊跟其后的字符取字面值。例如:

itcast$ echo $SHELL?

/bin/bash?

itcast$ echo \$SHELL?

$SHELL itcast

$ echo \\?

\

比如創(chuàng)建一個(gè)文件名為“$ $”的文件可以這樣:

itcast$ touch \$\ \$

還有一個(gè)字符雖然不具有特殊含義,但是要用它做文件名也很麻煩,就是-號(hào)。如果要?jiǎng)?chuàng)建一個(gè)文件名以-號(hào)開(kāi)頭的文件,這樣是不行的:

itcast$ touch -hello?

touch: invalid option -- h?

Try `touch --help' for more information.

即使加上\轉(zhuǎn)義也還是報(bào)錯(cuò):

itcast$ touch \-hello?

touch: invalid option -- h?

Try `touch --help' for more information.

因?yàn)楦鞣NUNIX命令都把-號(hào)開(kāi)頭的命令行參數(shù)當(dāng)作命令的選項(xiàng),而不會(huì)當(dāng)作文件名。如果非要處理以-號(hào)開(kāi)頭的文件名,可以有兩種辦法:

itcast$ touch ./-hello

或者

itcast$ touch -- -hello

\還有一種用法,在\后敲回車表示續(xù)行,Shell并不會(huì)立刻執(zhí)行命令,而是把光標(biāo)移到下一行,給出一個(gè)續(xù)行提示符>,等待用戶繼續(xù)輸入,最后把所有的續(xù)行接到一起當(dāng)作一個(gè)命令執(zhí)行。例如:

itcast$ ls \?

> -l?

(ls -l命令的輸出)

單引號(hào)

和C語(yǔ)言不一樣,Shell腳本中的單引號(hào)和雙引號(hào)一樣都是字符串的界定符(雙引號(hào)下一節(jié)介紹),而不是字符的界定符。單引號(hào)用于保持引號(hào)內(nèi)所有字符的字面值,即使引號(hào)內(nèi)的\和回車也不例外,但是字符串中不能出現(xiàn)單引號(hào)。如果引號(hào)沒(méi)有配對(duì)就輸入回車,Shell會(huì)給出續(xù)行提示符,要求用戶把引號(hào)配上對(duì)。例如:

itcast$ echo '$SHELL'?

$SHELL?

itcast$ echo 'ABC\(回車)?

> DE'(再按一次回車結(jié)束命令)?

ABC\?

DE

雙引號(hào)

被雙引號(hào)用括住的內(nèi)容,將被視為單一字串。它防止通配符擴(kuò)展,但允許變量擴(kuò)展。這點(diǎn)與單引號(hào)的處理方式不同

itcast$ DATE=$(date)

itcast$ echo "$DATE"?

itcast$ echo '$DATE'


shell編程——基本語(yǔ)法的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國(guó)家法律
敦煌市| 清徐县| 凤阳县| 巴林左旗| 孝义市| 金门县| 六盘水市| 凤翔县| 阿克苏市| 西宁市| 格尔木市| 克拉玛依市| 玉屏| 张家川| 江达县| 梁平县| 滕州市| 鲁山县| 思南县| 汝阳县| 广灵县| 南部县| 禹州市| 清水河县| 临清市| 霸州市| 申扎县| 六安市| 平阴县| 安福县| 沭阳县| 新巴尔虎左旗| 邵阳市| 达拉特旗| 垦利县| 沂南县| 马关县| 卢湾区| 读书| 通河县| 石河子市|