国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

Shell編程

2019-11-18 17:24:39
字體:
來源:轉載
供稿:網友
在DOS中,你可能會從事一些例行的重覆性工作,此時你會將這些重覆性的命令寫成批次檔,只要執行這個批次檔就等於執行這些命令。大家會問在UNIX中是否有批次處理這個東東,答案是有的。在UNIX中不只有如DOS的批次處理,它的功能比起DOS更強大,相對地也較復雜,已經和一般的高階語言不相上下。在UNIX中大家都不叫做批次檔,而叫做ShellScript。

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

將文字檔設為可執行的ShellScript

如果我們已經寫好Script,如何將其設成可執行檔呢?因為Script其實是一個可執行檔,所以必須將其存取權設定成可執行。我們可以使用下列命令更改存取權:
chmodu xfilename只有自己可以執行,其它人不能執行
chmodug xfilename只有自己以及同一群可以執行,其它人不能執行
chmod xfilename所有人都可以執行

而我們如何指定使用那一個Shell來解釋所寫的Script呢?幾種基本的指定方式如下所述:
1.如果Script的第一個非空白字元不是"#",則它會使用BourneShell。
2.如果Script的第一個非空白字元是"#"時,但不以"#!"開頭時,則它會使用CShell。
3.如果Script以"#!"開頭,則"#!"後面所寫的就是所使用的Shell,而且要將整個路徑名稱指出來。

這里建議使用第三種方式指定Shell,以確保所執行的就是所要的。BourneShell的路徑名稱為/bin/sh,而CShell則為/bin/csh。


1.使用BourneShell
┌——————————┐┌——————————┐
│echoenterfilename││#!/bin/sh│
│.│or│.│
│.││.│
│.││.│
└——————————┘└——————————┘

2.使用CShell
┌——————————┐┌——————————┐
│#CShellScript││#!/bin/csh│
│.││.│
│.││.│
│.││.│
└——————————┘└——————————┘

3.使用/etc/perl
┌——————————┐
│#!/etc/perl│
│.│
│.│
│.│
└——————————┘

除了在Script內指定所使用的Shell外,你也可以在命令列中強制指定。比如你要用CShell執行某個Script,你可以下這個命令:
cshfilename

此時的Script的存取權就不一定要為可執行檔,其內部所指定的Shell也會無效,詳細的情形後面會討論。

□Script的基本結構及觀念

Script是以行為單位,我們所寫的Script會被分解成一行一行來執行。而每一行可以是命令、注解、或是流程控制指令等。如果某一行尚未完成,可以在行末加上"/",這個時候下一行的內容就會接到這一行的後面,成為同一行,如下

┌———————————┐
│echoThemessageis/│
│toolongsowehave/│
│tosplititinto/│
│severallines│
└———————————┘

當Script中出現"#"時,再它後面的同一行文字即為注解,Shell不會對其翻譯

在Script中要執行一個命令的方法和在命令列中一樣,你可以前景或背景執行,執行命令時也會需要設定一些環境變數。

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

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

□BourneShell

一、變數

BourneShell的變數型態只有字串變數,所以要使用數值運算則必須靠外部命令達成目的。而其變數種類有下列幾種:

1.使用者變數

這是最常使用的變數,我們可以任何不包含空白字元的字串來當做變數名稱。設定變數值時則用下列方式:
var=string

取用變數時則在變數名稱前加上一"$"號。


┌———————┐
│name=Tom│
│echoname│
│echo$name│
└———————┘
結果如下:
name
Tom

2.系統變數(環境變數)

和使用者變數相似,只不過此種變數會將其值傳給其所執行的命令。要將一使用者變數設定為系統變數,只要加上:
exportvar

┌———————┐
│name=Tom│
│exportname│
└———————┘

以下是使用者一進入系統之後就已設定好的系統變數:
$HOME使用者自己的目錄
$PATH執行命令時所搜尋的目錄
$TZ時區
$MAILCHECK每隔多少秒檢查是否有新的信件
$PS1在命令列時的提示號
$PS2當命令尚未打完時,Shell要求再輸入時的提示號
$MANPATHman指令的搜尋路徑

3.唯讀的使用者變數

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

而若只打readonly則會列出所有唯讀的變數。還有一點,系統變數不可以設定成唯讀的。

┌———————┐
│name=Tom│
│readonlyname│
│echo$name│
│name=John│
│readonly│
└———————┘

結果如下:
Tom
name:isreadonly
readonlyname
readonly......

4.特殊變數

有些變數是一開始執行Script時就會設定,并且不以加以修改,但我們不叫它唯讀的系統變數,而叫它特殊變數(有些書會叫它唯讀的系統變數),因為這些變數是一執行程式時就有了,況且使用者無法將一般的系統變數設定成唯讀的。以下是一些等殊變數:
$0這個程式的執行名字
$n這個程式的第n個參數值,n=1..9
$*這個程式的所有參數
$#這個程式的參數個數
$$這個程式的PID
$!執行上一個背景指令的PID
$?執行上一個指令的返回值

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

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

檔名:ex1參數:thisisatest

┌———————————┐
│echoFilename:$0│
│echoArguments:$*│
│echoNo.ofargs.:$#│
│echo2ndarg.:$2│
│shift│
│echoNo.ofargs.:$#│
│echo2ndarg.:$2│
│sethello,everyone│
│echoArguments:$*│
│echo2ndarg.:$2│
└———————————┘
結果如下:
Filename:ex1
Arguments:thisisatest
No.ofargs.:4
2ndarg.:is
No.ofargs.:3
2ndarg.:a
Arguments:hello,everyone
2ndarg.:everyone

值得一提的是,當你想從鍵盤輸入一變數值時,你可以使用下面的命令:
readvar1var2.....

這時read會將一個字分給一個變數。如果輸入的字比變數還多,最後一個變數會將剩下的字當成其值。如果輸入的字比變數還少,則後面的變數會設成空字串。如果需要處理數值運算,我們可以使用ex
number=`expr$number 1`
這就是先前所提要作數值運算的方法,基本上expr命令只將運算式解,而後輸出到標準輸出上。如果要將某變數設定成其值,非得靠命令替換的方式不可。這個例子是將number變數的值加1後再存回number變數。

三、流程控制

在介紹流程控制之前,我們先來看看test命令。test命令的參數是條件判斷式,當條件為真時則傳回非零值,而條件為偽時則傳回零。在所有的流程控制都必須用到test命令來判斷真偽。而test命令的使用方法則列於附錄B。

test$#=0

如果執行這個程式沒有參數時,會傳回非零值代表"$#=0"這個條件成立。反之則會傳回零。

以下介紹各種流程控制:

1.ifthen語法以及流程圖如下

│FALSE
if(condition)<condition>—┐
then│TRUE│
then-commandsthen-commands│
fi├————┘



condition是一個test命令。往後所介紹的各種流程中的condition都是test命令。
檔名:chkarg

┌———————————┐
│if(test$#!=0)│
│then│
│echoArg1:$1│
│fi│
└———————————┘
$chkargHello
Arg1:Hello
$chkarg
$

2.ifthenelse語法以及流程圖如下

│FALSE
if(condition)<condition>—————┐
then│TRUE│
then-commandsthen-commandselse-commands
else├————————┘
else-commands│
fi

3.ifthenelif語法以及流程圖如下

│FALSE
if(condition1)<condition1>—┐
then│TRUE│FALSE
commands1commands1<condition2>—┐
elif(condition2)││TRUE│
then│commands2commands3
commands2├—————┴————┘
else│
commands3

commands3
fi


echo'
Word1:/c'
readword1
echo'word2:/c'
readword2
echo'word3:/c'
readword3
if(test"$word1"="$word2"-a"$word2"="$word3")
then
echo'Match:words1,2,&3'
elif(test"$word1"="$word2")
then
echo'Match:words1&2'
elif(test"$word1"="$word3")
then
echo'Match:words1&3'
elif(test"$word2"="$word3")
then
echo'Match:words2&3'
else
echo'Nomatch'
fi

4.forin語法以及流程圖如下

│FALSE
forvarinarg-list┌—<arg-list還有東西嗎?>—┐
do││TRUE│
commands│從arg-list取得一項│
done│放到變數var│
│││
│commands│
└——————┘│
┌———————————┐┌—————┘
│forainxxyyzz││
│do│
│echo$a│
│done│
└———————————┘
結果如下:
xx
yy

yy
zz

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

│FALSE
forvar┌—<參數中還有東西嗎?>—┐
do││TRUE│
commands│從參數中取得一項│
done│放到變數var│
│││
│commands│
└—————┘│
檔名:lstarg┌—————┘
┌———————————┐│
│fora│
│do│
│echo$a│
│done│
└———————————┘
$lstargxxyyzz
xx
yy

yy
zz

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


│FALSE
while(condition)┌—<condition>—┐
do││TRUE│
commands│commands│
done└————┘│
┌————┘


┌———————————————┐
│number=0│
│while(test$number-lt10)│
│do│
│echo"$number/c"│
│number=`expr$number 1`│
│done│
│echo│
└———————————————┘
結果如下:
0123456789

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


│TRUE
until(condition)┌—<condition>—┐
do││FALSE│
commands│commands│
done└————┘│
┌————┘


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

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

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

│TRUE
casestrin<str=pat1>————commands1—┐
pat1)commands1;;│FALSETRUE│
pat2)commands2;;<str=pat2>————commands2—┤
pat3)commands3;;│FALSETRUE│
esac<str=pat3>————commands3—┤
│FALSE│
├————————————┘


而pat除了可以指定一些確定的字串,也可以指定字串的集合,如下
*任意字串
?任意字元
[abc]a,b,或c三字元其中之一
[a-n]從a到n的任一字元
|多重選擇

┌———————————————┐
│echo'EnterA,B,orC:/c'│
│readletter│
│case$letterin│
│A|a)echo'YouenteredA.';;│
│B|b)echo'YouenteredB.';;│
│C|c)echo'YouenteredC.';;│
│*)echo'NotA,B,orC';;│
│esac│
└————————

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 永安市| 大城县| 泾川县| 通州市| 洞口县| 沙田区| 汨罗市| 平江县| 奇台县| 二连浩特市| 禄劝| 蒙城县| 当阳市| 社旗县| 郎溪县| 合水县| 自治县| 长葛市| 依安县| 南华县| 邯郸县| 漾濞| 营口市| 乳山市| 桑日县| 沛县| 济南市| 金堂县| 习水县| 闽清县| 炎陵县| 江西省| 利津县| 壶关县| 吐鲁番市| 雷州市| 沂南县| 九江县| 江阴市| 梧州市| 宣汉县|