久久r热视频,国产午夜精品一区二区三区视频,亚洲精品自拍偷拍,欧美日韩精品二区

您的位置:首頁技術(shù)文章
文章詳情頁

UNIX SHELL腳本編程

瀏覽:5日期:2024-06-11 17:38:13

<<<目錄>>> □前言

□將文字檔設(shè)為可執(zhí)行的Shell Script

□Script的基本結(jié)構(gòu)及觀念

□Bourne Shell

一、變數(shù)

二、執(zhí)行命令

三、流程控制

□C Shell

一、變數(shù)

二、執(zhí)行命令

三、流程控制

□附錄A expr命令

□附錄B test命令

□前言

在Dos 中,你可能會(huì)從事一些例行的重覆性工作,此時(shí)你會(huì)將這些重覆性的命令寫 成批次檔,只要執(zhí)行這個(gè)批次檔就等於執(zhí)行這些命令。大家會(huì)問在Unix中是否有批次處 理這個(gè)東東,答案是有的。在UNIX中不只有如DOS 的批次處理,它的功能比起DOS 更強(qiáng) 大,相對(duì)地也較復(fù)雜,已經(jīng)和一般的高階語言不相上下。在UNIX中大家都不叫做批次檔 ,而叫做Shell Script。

一般而言,Shell Script的地位和其它的可執(zhí)行檔(或命令)是完全相同的,只不 過Shell Script是以文字檔的方式儲(chǔ)存,而非二進(jìn)位檔。而執(zhí)行Shell Script時(shí),必須 有一個(gè)程式將其內(nèi)容轉(zhuǎn)成一道道的命令執(zhí)行,而這個(gè)程式其實(shí)就是Shell ,這也就是為 什麼我們叫做Shell Script的原因(往後我們稱為Script)。不同Shell 的Script基本 上會(huì)有一些差異,所以我們不能將寫給A shell 的Script用B shell 執(zhí)行。而在UNIX中 大家最常使用Bourne Shell以及C Shell ,所以這堂課就介紹這兩種Script的寫法。

□將文字檔設(shè)為可執(zhí)行的Shell Script

如果我們已經(jīng)寫好Script,如何將其設(shè)成可執(zhí)行檔呢?因?yàn)镾cript其實(shí)是一個(gè)可執(zhí) 行檔,所以必須將其存取權(quán)設(shè)定成可執(zhí)行。我們可以使用下列命令更改存取權(quán):

chmod u+x filename 只有自己可以執(zhí)行,其它人不能執(zhí)行

chmod ug+x filename 只有自己以及同一群可以執(zhí)行,其它人不能執(zhí)行

chmod +x filename 所有人都可以執(zhí)行

而我們?nèi)绾沃付ㄊ褂媚且粋€(gè)Shell 來解釋所寫的Script呢?幾種基本的指定方式如 下所述:

1. 如果Script的第一個(gè)非空白字元不是'#',則它會(huì)使用Bourne Shell。

2. 如果Script的第一個(gè)非空白字元是'#'時(shí),但不以'#!'開頭時(shí),則它會(huì)使用C Shell。

3. 如果Script以'#!'開頭,則'#!'後面所寫的就是所使用的Shell,而且要將整個(gè)路徑 名稱指出來。這里建議使用第三種方式指定Shell ,以確保所執(zhí)行的就是所要的。Bourne Shell的路 徑名稱為/bin/sh ,而C Shell 則為/bin/csh。

除了在Script內(nèi)指定所使用的Shell 外,你也可以在命令列中強(qiáng)制指定。比如你要 用C Shell 執(zhí)行某個(gè)Script,你可以下這個(gè)命令:

csh filename

此時(shí)的Script的存取權(quán)就不一定要為可執(zhí)行檔,其內(nèi)部所指定的Shell 也會(huì)無效,詳細(xì) 的情形後面會(huì)討論。

□Script的基本結(jié)構(gòu)及觀念 Script是以行為單位,我們所寫的Script會(huì)被分解成一行一行來執(zhí)行。而每一行可 以是命令、注解、或是流程控制指令等。如果某一行尚未完成,可以在行末加上'' , 這個(gè)時(shí)候下一行的內(nèi)容就會(huì)接到這一行的後面,成為同一行,如下

echo the message is

too long so we have

to split it into

several lines.

當(dāng)Script中出現(xiàn)'#' 時(shí),再它後面的同一行文字即為注解,Shell 不會(huì)對(duì)其翻譯。

在Script中要執(zhí)行一個(gè)命令的方法和在命令列中一樣,你可以前景或背景執(zhí)行,執(zhí) 行命令時(shí)也會(huì)需要設(shè)定一些環(huán)境變數(shù)。

Script的流程控制和一般高階語言的流程控制沒有什麼兩樣,也和高階語言一樣有 副程式。這些使得Script的功能更加強(qiáng)大。

為了達(dá)到與高階語言相同的效果,我們也可以在Script中設(shè)定變數(shù),如此使Script 成為一個(gè)名付其實(shí)的高階語言。

□Bourne Shell

一、變數(shù)

Bourne Shell的變數(shù)型態(tài)只有字串變數(shù),所以要使用數(shù)值運(yùn)算則必須靠外部命令達(dá) 成目的。而其變數(shù)種類有下列幾種:

1. 使用者變數(shù) 這是最常使用的變數(shù),我們可以任何不包含空白字元的字串來當(dāng)做變數(shù)名稱。 設(shè)定變數(shù)值時(shí)則用下列方式:

var=string 取用變數(shù)時(shí)則在變數(shù)名稱前加上一'$' 號(hào)。

name=Tom

echo name

echo $name

結(jié)果如下:

name

Tom

2. 系統(tǒng)變數(shù)(環(huán)境變數(shù))

和使用者變數(shù)相似,只不過此種變數(shù)會(huì)將其值傳給其所執(zhí)行的命令。要將一使 用者變數(shù)設(shè)定為系統(tǒng)變數(shù),只要加上:

export var

name=Tom

export name

以下是使用者一進(jìn)入系統(tǒng)之後就已設(shè)定好的系統(tǒng)變數(shù):

$HOME 使用者自己的目錄

$PATH 執(zhí)行命令時(shí)所搜尋的目錄

$TZ 時(shí)區(qū)

$MAILCHECK 每隔多少秒檢查是否有新的信件

$PS1 在命令列時(shí)的提示號(hào)

$PS2 當(dāng)命令尚未打完時(shí),Shell 要求再輸入時(shí)的提示號(hào)

$MANPATH man 指令的搜尋路徑

3. 唯讀的使用者變數(shù)

和使用者變數(shù)相似,只不過這些變數(shù)不能被改變。要將使用者變數(shù)設(shè)成唯讀的 ,只要加上:

readonly var 而若只打readonly則會(huì)列出所有唯讀的變數(shù).還有一點(diǎn),系統(tǒng)變數(shù)不可以設(shè)定 成唯讀的。

name=Tom

readonly name

echo $name

name=John

readonly

結(jié)果如下: Tom name: is read only readonly name readonly ......

4. 特殊變數(shù)

有些變數(shù)是一開始執(zhí)行Script時(shí)就會(huì)設(shè)定,并且不以加以修改,但我們不叫它 唯讀的系統(tǒng)變數(shù),而叫它特殊變數(shù)(有些書會(huì)叫它唯讀的系統(tǒng)變數(shù)),因?yàn)檫@ 些變數(shù)是一執(zhí)行程式時(shí)就有了,況且使用者無法將一般的系統(tǒng)變數(shù)設(shè)定成唯讀 的。以下是一些等殊變數(shù):

$0 這個(gè)程式的執(zhí)行名字

$n 這個(gè)程式的第n個(gè)參數(shù)值,n=1..9 $* 這個(gè)程式的所有參數(shù)

$# 這個(gè)程式的參數(shù)個(gè)數(shù)

$$ 這個(gè)程式的PID $! 執(zhí)行上一個(gè)背景指令的PID

$? 執(zhí)行上一個(gè)指令的返回值

當(dāng)你執(zhí)行這個(gè)程式時(shí)的參數(shù)數(shù)目超過9 個(gè)時(shí),我們可以使用shift 命令將參數(shù) 往前移一格,如此即可使用第10個(gè)以後的參數(shù)。除此之外,吾人可以用set 命 令改變$n及$*,方法如下:

set string 如此$*的值即為string,而分解後則會(huì)放入$n。如果set 命令後面沒有參數(shù), 則會(huì)列出所有已經(jīng)設(shè)定的變數(shù)以及其值。

檔名:ex1 參數(shù):this is a test

echo Filename: $0

echo Arguments: $*

echo No. of args.: $#

echo 2nd arg.: $2

shift

echo No. of args.: $#

echo 2nd arg.: $2

set hello, everyone

echo Arguments: $*

echo 2nd arg.: $2

結(jié)果如下:

Filename: ex1

Arguments: this is a test No. of args.: 4

2nd arg.: is

No. of args.: 3

2nd arg.: a

Arguments: hello, everyone

2nd arg.: everyone

值得一提的是,當(dāng)你想從鍵盤輸入一變數(shù)值時(shí),你可以使用下面的命令:

read var1 var2..... 這時(shí)read會(huì)將一個(gè)字分給一個(gè)變數(shù)。如果輸入的字比變數(shù)還多,最後一個(gè)變數(shù)會(huì)將 剩下的字當(dāng)成其值。如果輸入的字比變數(shù)還少,則後面的變數(shù)會(huì)設(shè)成空字串。 如果需要處理數(shù)值運(yùn)算,我們可以使用expr命令。其參數(shù)及輸出列於附錄A。

二、執(zhí)行命令

在Bourne Shell中有五種方法執(zhí)行一個(gè)命令,而這五種方式所產(chǎn)生的果有些許的不 同。

1. 直接下命令 這個(gè)方式和在命令列中直接下命令的效果一樣。

2. 使用sh命令 sh command 這個(gè)檔案必須是Bourne Shell的Script,但這個(gè)檔案并不一定要設(shè)成可執(zhí)行。 除此之外和直接下命令的方式一樣。

3. 使用'.'命令 . command 這時(shí)和使用sh命令相似,只不過它不像sh一般會(huì)產(chǎn)生新的process ,相反地, 它會(huì)在原有的process 下完成工作。

4. 使用exec命令 exec command 此時(shí)這個(gè)Script將會(huì)被所執(zhí)行的命令所取代。當(dāng)這個(gè)命令執(zhí)行完畢之後,這個(gè) Script也會(huì)隨之結(jié)束。

5. 使用命令替換 這是一個(gè)相當(dāng)有用的方法。如果想要使某個(gè)命令的輸出成為另一個(gè)命令的參數(shù) 時(shí),就一定要使用這個(gè)方法。我們將命令列於兩個(gè)'`' 號(hào)之間,而Shell 會(huì)以 這個(gè)命令執(zhí)行後的輸出結(jié)果代替這個(gè)命令以及兩個(gè)'`' 符號(hào)。

str='Current Directory is '`pwd` echo $str

結(jié)果如下:

Current directory is /users/cc/mgtsai

這個(gè)意思是pwd 這個(gè)命令輸出'/users/cc/mgtsai',而後整個(gè)字串代替原 來的`pwd` 設(shè)定str 變數(shù),所以str 變數(shù)的內(nèi)容則會(huì)有pwd 命令的輸出。

number=`expr $number + 1` 這就是先前所提要作數(shù)值運(yùn)算的方法,基本上expr命令只將運(yùn)算式解,而 後輸出到標(biāo)準(zhǔn)輸出上。如果要將某變數(shù)設(shè)定成其值,非得靠命令替換的方 式不可。這個(gè)例子是將number變數(shù)的值加1 後再存回number變數(shù)。

三、流程控制 在介紹流程控制之前,我們先來看看test命令。test命令的參數(shù)是條件判斷式,當(dāng) 條件為真時(shí)則傳回非零值,而條件為偽時(shí)則傳回零。在所有的流程控制都必須用到 test命令來判斷真?zhèn)巍6鴗est命令的使用方法則列於附錄B。

test $# = 0 如果執(zhí)行這個(gè)程式?jīng)]有參數(shù)時(shí),會(huì)傳回非零值代表'$# = 0'這個(gè)條件成立。反 之則會(huì)傳回零。

以下介紹各種流程控制:

1. if then 語法以及流程圖如下 語法以及流程圖如下

if(condition)

then

then-commands

fi

condition 是一個(gè)test命令。往後所介紹的各種流程中的condition 都是test 命令。

檔名:chkarg

if(test$#!=0)

then

echo Arg1:$1

fi

$ chkarg Hello

Arg1: Hello

$ chkarg $

2. if then else 語法以及流程圖如下

if(condition)

then

then-commands

else

else-commands

fi

3. if then elif 語法以及流程圖如下

if(condition1)

then

commands1

elif(condition2)

then

commands2

else

commands3

fi

echo 'Word 1: c'

read word1

echo 'word 2: c'

read word2

echo 'word 3: c'

read word3

if (test '$word1' = '$word2' -a '$word2' = '$word3')

then

echo 'Match: words 1, 2, & 3'

elif (test '$word1' = '$word2')

then

echo 'Match: words 1 & 2'

elif (test '$word1' = '$word3')

then echo 'Match: words 1 & 3'

elif (test '$word2' = '$word3')

then

echo 'Match: words 2 & 3'

else

echo 'No match'

fi

4. for in 語法以及流程圖如下

for var in arg-list

do

commands

done

for a in xx yy zz

do

echo $a

done

結(jié)果如下:

xx yy yy zz

5. for 語法以及流程圖如下

for var

do commands

done

檔名:lstarg

for a

do

echo $a

done

$lstarg xx yy zz

xx yy yy zz

6. while 語法以及流程圖如下

while (condition)

do

commands

done

number=0

while (test $number -lt 10)

do

echo '$numberc'

number=`expr $number + 1`

done

echo

結(jié)果如下: 0123456789

7. until 語法以及流程圖如下

until (condition)

do

commands

done

它和while 的不同只在於while 是在條件為真時(shí)執(zhí)行回圈,而until 是在條件 為假時(shí)執(zhí)行回圈。

8. break及continue 這兩者是用於for, while, until 等回圈控制下。break 會(huì)跳至done後方執(zhí)行 ,而continue會(huì)跳至done執(zhí)行,繼續(xù)執(zhí)行回圈。

9. case 語法以及流程圖如下

case str in

pat1) commands1;;

pat2) commands2;;

pat3) commands3;;

esac

而pat 除了可以指定一些確定的字串,也可以指定字串的集合,如下

* 任意字串

? 任意字元

[abc] a, b, 或c三字元其中之一

[a-n] 從a到n的任一字元

| 多重選擇

echo 'Enter A, B, or C: c'

read letter

case $letter in

A|a) echo 'You entered A.';;

B|b) echo 'You entered B.';;

C|c) echo 'You entered C.';;

*) echo 'Not A, B, or C';;

esac

10. 函數(shù) 格式如下 function-name() { commands } 而要呼叫此函數(shù),就像在命令列下直接下命令一般。

□C Shell C Shell 有些特性和Bourne Shell一樣,但有些不相同。這里介紹與Bourne Shell 不相同的地方。

一、變數(shù)

1. 字串變數(shù) 這個(gè)部分和Bourne Shell的變數(shù)一樣,只不過在設(shè)定變數(shù)值時(shí)不能使用Bourne Shell的方式,而必須打:

set var=value

2. 數(shù)字運(yùn)算 基本上C Shell 沒有數(shù)字變數(shù),但C Shell 卻有簡單的方法處理數(shù)字運(yùn)算:

@ var operator expression

operator可以是C 語言中的=, +=, -=,......,而expression則是運(yùn)算式。運(yùn) 算式的運(yùn)算子如下:

A. () 改變計(jì)算的順序 ~@

B. ~ 位元NOT運(yùn)算 @~~ ! 邏輯否定

C. % 取馀數(shù) C. % 取馀數(shù) / 除 * 乘 - 減 + 加

D. >> 右移 << 左移

E. > 大於 < 小於 >= 大於等於 <= 小於等於 != 不等於 == 等於

F. & 位元AND運(yùn)算 ^ 位元XOR運(yùn)算 | 位元OR 運(yùn)算

G. && 邏輯AND || 邏輯OR

除此之外,我們也可以檢驗(yàn)一個(gè)檔案的狀態(tài),如下

-n filename

而-n可為下列之一

-d 檔案是一個(gè)目錄檔案

-e 檔案存在

-f 檔案為一般的檔案

-o 使用者擁有這個(gè)檔案

-r 使用者可以讀取這個(gè)檔案

-w 使用者可以寫入這個(gè)檔案

-x 使用者可以執(zhí)行這個(gè)檔案

-z 檔案長度為0

@ count = count + 1

@ flag = -e /users/cc/mgtsai/mail && -e /usr/spool/mail

3. 陣列

在C Shell 中,我們可以宣告陣列變數(shù),方式如下

set var=(val1 val2 ......) 而var[1]之值為val1,var[2]之值為val2......。而$var代表整個(gè)陣列。我們 可以用$#var 來計(jì)算陣列個(gè)數(shù),也可以用$?var 來檢查某個(gè)變數(shù)是否已宣告。

4. 特殊變數(shù)

$argv 和Bourne Shell的$*相似,只不過這是一個(gè)陣列。

$argv[n] 和Bourne Shell的$n相同,但不受個(gè)數(shù)限制。

$#argv 和Bourne Shell的$#相同

$home 和Bourne Shell的$HOME相同

$path 和Bourne Shell的$PATH相似,只不過這是一個(gè)陣列

$prompt 和Bourne Shell的$PS1相同

$shell Shell的路徑名稱 $status 和Bourne Shell的$?相同

$$ 和Bourne Shell的$$相同

$< 鍵盤輸入

二、執(zhí)行命令

基本上和Bourne Shell相同,只有一點(diǎn)在Bourne Shell中的'.' 命令在C Shell 中 則為'source'命令。

三、流程控制

在C Shell 中流程控制不像Bourne Shell中一般需要使用test命令。相反地,它和 C 語言類似只要在條件中寫出運(yùn)□式即可。當(dāng)運(yùn)算結(jié)果不為零時(shí),其值為真,為零 時(shí)其值為偽。以下是C Shell的流程控制

1. if 語法如下

if (expression) simple-command

2. goto 語法如下

goto label

這時(shí)程式會(huì)跳至以l'label:'開頭的那一行執(zhí)行

if ($#argv == 2) goto goodargs

echo 'Please use two arguments.'

exit

goodrags: ...

3. if then else

這和Bourne Shell的if then, if then else, if then elif 相似。語法如下

A. if (expression) then commands endif

B. if (expression) then commands else commands endif

C. if (expression) then commands else if (expression) then commands else commands endif

4. foreach 這和Bourne Shell的for in相似。語法如下

foreach var (arg-list)

commands

end

5. while 這和Bourne Shell的while相似。語法如下

while (expression)

commands

end

6. break及continue

這和Bourne Shell的break 及continue相似,是用來中斷foreach 及while 回 圈。

7. switch 這和Bourne Shell的case相似。語法如下

switch (string)

case pat1:

commands1

breaksw

case pat2:

commands2

breaksw

case pat3:

commands3

breaksw

endsw

□附錄A expr命令

命令格式

expr expression

敘述

expression是由字串以及運(yùn)算子所組成,每個(gè)字串或是運(yùn)算子之間必須用空白隔開 。下表是運(yùn)算子的種類及功能,而優(yōu)先順序則以先後次序排列,我們可以利用小括 號(hào)來改變運(yùn)算的優(yōu)先次序。其運(yùn)算結(jié)果則輸出至標(biāo)準(zhǔn)輸出上。

: 字串比較。比較的方式是以兩字串的第一個(gè)字母開始,而以第二個(gè)字串的 字母結(jié)束。如果相同時(shí),則輸出第二個(gè)字串的字母?jìng)€(gè)數(shù),如果不同時(shí)則傳 回0 。

* 乘法

/ 除法

% 取馀數(shù)

+ 加法

- 減法

< 小於

<= 小於等於

= 等於

!= 不等於

>= 大於等於

> 大於

& AND運(yùn)算

| OR運(yùn)算

當(dāng)expression中含有'*', '(', ')' 等符號(hào)時(shí),必須在其前面加上'' ,以免被 Shell 解釋成其它意義。

expr 2 * ( 3 + 4 ) 其輸出為14

□附錄B test命令

命令格式

test expression

敘述

expression中包含一個(gè)以上的判斷準(zhǔn)則以作為test評(píng)詁的標(biāo)準(zhǔn)。兩準(zhǔn)則間用'-a'代 表邏輯AND 運(yùn)算,'-o'代表邏輯OR運(yùn)算,而在準(zhǔn)則前放置一'!' 代表NOT 運(yùn)算。如 果沒有括號(hào),則優(yōu)先權(quán)則為'!' > '-a' > '-o' 。和expr命令相同,相使用左右括 號(hào)時(shí),必須在其前面加上'' 。以下是有關(guān)準(zhǔn)則的敘述(合敘述時(shí)傳回真,否則傳 回偽):

string string不為空白字串

-n string string的長度大於0

-z string string的長度等於0

string1=string2 string1等於string2

string1!=string2 string1不等於string2

int1 -gt int2 int1大於int2

int1 -ge int2 int1大於等於int2

int1 -eq int2 int1等於int2

int1 -ne int2 int1不等於int2

int1 -le int2 int1小於等於int2

int1 -lt int2 int1小於int2

-r filename 檔案可讀取

-w filename 檔案可寫入

-x filename 檔案可執(zhí)行

-f filename 檔案為一般檔

-d filename 檔案為目錄

-s filename 檔案為非空的一般檔

test -r '$filename' -a -s '$filename'

標(biāo)簽: Unix系統(tǒng)
主站蜘蛛池模板: 建始县| 开远市| 邹平县| 大渡口区| 轮台县| 河北省| 九台市| 德化县| 平顶山市| 怀化市| 五常市| 五峰| 江川县| 南康市| 大城县| 余江县| 旺苍县| 克拉玛依市| 民权县| 泽库县| 宣城市| 临夏市| 泗水县| 南部县| 甘肃省| 河东区| 凌源市| 虎林市| 西华县| 拜泉县| 夏邑县| 镇江市| 兖州市| 岑溪市| 高唐县| 河北省| 博兴县| 乌苏市| 红安县| 桐庐县| 荣昌县|