Bourne Shell及shell程式設計(轉)
Bourne Shell及shell程式設計(轉)[@more@](文:何斌武)Bourne Shell介紹:Bourne Shell 基礎及其他很多有用的特性,shell程式設計及組織。主要內容:.shell基礎 基本介紹,環境,選項,特殊字元.shell變數 使用者定義變數,環境變數,位置變數(shell 引數).shell script程式設計條件測試,迴圈及重複控制.shell定製1.shell基礎知識作者:Stephen Bourne 在Bell實驗室開發建議:man sh 檢視相關UNIX上的改進或特性(1)shell提示符及其環境/etc/passwd檔案提示符:$/etc/profile $HOME/.profile(2)shell執行選項-n 測試shell script語法結構,只讀取shell script但不執行-x 進入跟蹤方式,顯示所執行的每一條命令,用於排程-a Tag all variables for export-c "string" 從strings中讀取命令-e 非互動方式-f 關閉shell檔名產生功能-h locate and remember functions as defind-i 互動方式-k 從環境變數中讀取命令的引數-r 限制方式-s 從標準輸入讀取命令-t 執行命令後退出(shell exits)-u 在替換中如使用未定義變數為錯誤-v verbose,顯示shell輸入行這些選項可以聯合使用,但有些顯然相互衝突,如-e和-i.(3)受限制shell(Restircted Shell)sh -r 或 /bin/rsh不能執行如下操作:cd, 更改PATH,指定全路徑名,輸出重定向,因此可以提供一個較好的控制和安全機制。通常rsh用於應用型使用者及撥號使用者,這些使用者通常是看不到提示符的。通常受限制使用者的主目錄是不可寫的。不足:如果使用者可以呼叫sh,則rsh的限制將不在起作用,事實上如果使用者在vi及more程式中呼叫shell,而這時rsh的限制將不再起作用。(4)用set改變 shell選項使用者可以在$提示符下用set命令來設定或取消shell的選項。使用-設定選項,+取消相應選項,大多數UNIX系統允許a,e,f,h,k,n,u,v和x的開關設定/取消。set -xv啟動跟蹤方式;顯示所有的命令及替換,同樣顯示輸入。set -tu關閉在替換時對未定義變數的檢查。使用echo $-顯示所有已設定的shell選項。(5)使用者啟動檔案 .profilePATH=$PATH:/usr/loacl/bin; export PATH(6)shell環境變數CDPATH 用於cd命令的查詢路徑HOME /etc/passwd檔案中列出的使用者主目錄IFS Internal Field Separator,預設為空格,tab及換行符MAIL /var/mail/$USERNAME mail等程式使用PATHPS1,PS2 預設提示符($)及換行提示符(> )TERM 終端型別,常用的有vt100,ansi,vt200,xterm等示例:$PS1="test:";export PS1test: PS1="$";export PS1$echo $MAIL/var/mail/username(7)保留字元及其含義$ shell變數名的開始,如$var| 管道,將標準輸出轉到下一個命令的標準輸入# 註釋開始& 在後臺執行一個程式? 匹配一個字元* 匹配0到多個字元(與DOS不同,可在檔名中間使用,並且含.)$- 使用set及執行時傳遞給shell的標誌位$! 最後一個子程式的程式號$# 傳遞給shell script的引數個數$* 傳遞給shell script的引數$@ 所有引數,個別的用雙引號括起來$? 上一個命令的返回程式碼$0 當前shell的名字$n (n:1-) 位置引數$$ 程式標識號(Process Identifier Number, PID)>file 輸出重定向`command` 命令替換,如 filename=`basename /usr/local/bin/tcsh`>>fiile 輸出重定向,append轉義符及單引號:$echo "$HOME $PATH"/home/hbwork /opt/kde/bin:/usr/local/bin:/bin:/usr/bin:/usr/X11R6/bin:$echo '$HOME $PATH'$HOME $PATH$echo $HOME $PATH$HOME /opt/kde/bin:/usr/local/bin:/bin:/usr/bin:/usr/X11R6/bin:/home/hbwork/bin其他:$dir=ls$$dir$alias dir ls$dirls > filelistls >> filelistwc -l < filelistwc -l filelistsleep 5; echo 5 seconds reaches; ls -lps ax |egrep inetdfind / -name core -exec rm {} ; &filename=`date "+%Y%m%d"`.log2. shell變數變數:代表某些值的符號,如$HOME,cd命令查詢$HOME,在計算機語言中可以使用變數可以進行多種運算和控制。Bourne Shell有如下四種變數:.使用者自定義變數.位置變數即 shell script之引數.預定義變數(特殊變數).環境變數(參考shell定製部分)(1)使用者自定義變數(資料的儲存)$ COUNT=1$ NAME="He Binwu"技巧:因為大部分UNIX命令使用小寫字元,因此在shell程式設計中通常使用全大寫變數,當然這並不是強制性的,但使用大寫字元可以在程式設計中方便地識別變數。變數的呼叫:在變數前加$$ echo $HOME/home/hbwork$ WEEK=Satur$ echo Today is $WEEKdayToday is$echo Today is ${WEEK}dayToday is SaturdayShell變數賦值從右從左進行(Linux Shell/bash從左向右賦值!)$ X=$Y Y=y$ echo $Xy$ Z=z Y=$Z$ echo $Y$使用unset命令刪除變數的賦值$ Z=hello$ echo $Zhello$ unset Z$ echo $Z$有條件的命令替換在Bourne Shell中可以使變數替換在特定條件下執行,即有條件的環境變數替換。這種變數替換總是用大括號括起來的。.設定變數的預設值在變數未賦值之前其值為空。Bourne Shell允許對變數設定預設值,其格式如下:${variable:-defaultvalue}例:$ echo Hello $UNAMEHello$ echo Hello ${UNAME:-there}Hello there$ echo $UNAME #變數值並未發生變化$ UNAME=hbwork$ echo Hello ${UNAME:-there}Hello hbwork$.另一種情況:改變變數的值,格式如下:${variable:=value}例:$ echo Hello $UNAMEHello$ echo Hello ${UNAME:=there}Hello there$ echo $UNAME #變數值並未發生變化there$.變數替換中使用命令替換$USERDIR=${$MYDIR:-`pwd`}.在變數已賦值時進行替換 ${variable:+value}.帶有錯誤檢查的有條件變數替換${variable:?value}例:$ UNAME=$ echo ${UNAME:?"UNAME has not been set"}UNAME: UNAME has not been set$ echo ${UNAME:?}UNAME: parameter null or not set(2)位置變數(Shell引數)在shell script中位置引數可用$1..$9表示,$0表示內容通常為當前執行程式的檔名。.防止變數值被替換 readonly variable.使用export命令輸出變數,使得變數對子shell可用,當shell執行一下程式時,shell將為其設定一個新的環境讓其執行,這稱之了subshell. 在Bourne Shell中變數通常被認為是本地變數,也就是說在對其賦值之外的shell環境之外是不認識此變數的。使用export對subshell可用。例:對變數PS1的export操作,shell的提示符將發生變化。$ PS1=`hostname`$peony$sh$ echo $PS1$ $ exitpeony$export PS1peony$shpeony$ echo $PS1peony$ peony$3.Shell Script程式設計目的:使用UNIX所提供的最常用工具來完成所需複雜任務的強大功能。(1)最簡單的Shell 程式設計$ls -R / |grep myname |more每天資料的備份:$ cd /usr/yourname; ls * |cpio -o > /dev/rmt/0h書寫程式的目的是一次程式設計,多次使用(執行)!$ cat > backup.shcd /home/hbworkls * | cpio -o > /dev/rmt/0h^D執行:$ sh backup.sh或:$ chmod +x backup.sh$ ./backup.sh技巧:在shell script中加入必要的註釋,以便以後閱讀及維護。(2)shell是一個(程式設計)語言同傳統的程式語言一樣,shell提供了很多特性,這些特性可以使你的shell script程式設計更為有用,如:資料變數、引數傳遞、判斷、流程控制、資料輸入和輸出,子程式及以中斷處理等。. 在shell程式設計中使用資料變數可以將程式變數更為通用,如在上面backup.sh中:cd $WORKDIRls * | cpio -o > /dev/rmt/0h. Shell程式設計中的註釋以#開頭. 對shell變數進行數字運算,使用expr命令expr integer operator integer其中operator為+ - * / %, 但對*的使用要用轉義符,如:$expr 4 * 520$int=`expr 5 + 7`$echo $int12(3)Shell程式設計的引數傳遞, 可透過命令列引數以及互動式輸入變數(read)restoreall.sh 對backup.sh程式的備份磁帶進行恢復$cat > restoreall.shcd $WORKDIRcpio -i < /dev/rmt/0h^Drestore1.sh:只能恢復一個檔案#restore1 --program to restore a single filecd $WORKDIRcpio -i $i < /dev/rmt/0h$restore1 file1恢復多個檔案restoreany :#restoreany --program to restore a single filecd $WORKDIRcpio -i $* < /dev/rmt/0h$ restoreany file1 file2 file3(4)條件判斷. if-then語句,格式如下:if command_1thencommand_2command_3ficommand_4在if-then語句中使用了命令返回碼$?,即當command_1執行成功時才執行command_2和command_3,而command_4總是執行.示例程式unload: 在備份成功時刪除原始檔案,帶有錯誤檢查cd $1#備份時未考慮不成功的情況!ls -a | cpio -o > /dev/rmt/0hrm -rf *改進如下:#當使用了管道命令時,管理命令的返回程式碼為最後一個命令的返回程式碼if ls -a | cpio -o > /dev/rmt/0hthenrm -rf *fi. if-then-else語句if command_1thencommand_2elsecommand_3fi技巧: 由於shell對命令中的多餘的空格不作任何處理,一個好的程式設計師會用這一特性對自己的程式採用統一的縮排格式,以增強自己程式的可讀性.. 使用test命令進行進行條件測試格式: test conditionstest在以下四種情況下使用: a. 字元比較 b.兩個整數值的比較c. 檔案操作,如檔案是否存在及檔案的狀態等d. 邏輯操作,可以進行and/or,與其他條件聯合使用a. 測試字元資料: shell變數通常民政部下均作為字元變數str1 = str2 二者相長,相同str1 != str2 不同-n string string不為空(長度不為零)-z string string為空string string不為空例:$ str1=abcd #在含有空格時必須用引號括起來$ test $str1=abcd$ echo $?0$ str1="abcd "$ test $str1=abcd$ echo $?1Note: 在test處理含有空格的變數時最好用引號將變數括起來,否則會出現錯誤的結果,因為shell在處理命令列時將會去掉多餘的空格,而用引號括起來則可以防止shell去掉這些空格.例:$ str1=" "$ test $str1$ echo $?1$ test "$str1"$ echo $?0$ test -n $str1test: argument expected$ test -n "$str1"$ echo $?0$b. 整數測試: test與expr相同,可以將字元型變數轉換為整數進行操作,expr進行整數的算術運算,而test則進行邏輯運算.表示式 說明---------------------------------------int1 -eq int2 相等?int1 -ne int2 不等?int1 -gt int2 int1 > int2 ?int1 -ge int2 int1 >= int2 ?int1 -lt int2 int1 < int2 ?int1 -le int2 int1 <= int2 ?例:$ int1=1234$ int2=01234$ test $int1 -eq $int2$ echo $?0c. 檔案測試:檢查檔案狀態如存在及讀寫許可權等-r filename 使用者對檔案filename有讀許可權?-w filename 使用者對檔案filename有寫許可權?-x filename 使用者對檔案filename有可執行許可權?-f filename 檔案filename為普通檔案?-d filename 檔案filename為目錄?-c filename 檔案filename為字元裝置檔案?-b filename 檔案filename為塊裝置檔案?-s filename 檔案filename大小不為零?-t fnumb 與檔案描述符fnumb(預設值為1)相關的裝置是一個終端裝置?d. 測試條件之否定,使用!例:$ cat /dev/null > empty$ test -r empty$ echo $?0$ test -s empty1$ test ! -s empty$ echo $?0e. 測試條件之邏輯運算-a And-o Or例: $ test -r empty -a -s empty$ echo $?1f. 進行test測試的標準方法因為test命令在 shell程式設計中佔有很重要的地位,為了使shell能同其他程式語言一樣便於閱讀和組織, Bourne Shell在使用test測試時使用了另一種方法:用方括號將整個test測試括起來:$ int1=4$ [ $int1 -gt 2 ]$ echo $?0例: 重寫unload程式,使用test測試#!/bin/sh#unload - program to backup and remove files#syntax: unload directory#check argumentsif [ $# -ne 1 ]thenecho "usage: $0 directory"exit 1fi#check for valid directory nameif [ ! -d "$1" ]thenecho "$1 is not a directory"exit 2ficd $1ls -a | cpio -o > /dev/rmt/0hif [ $? -eq 0 ]thenrm -rf *elseecho "A problem has occured in creating backup"echo "The directory will not be ereased"echo "Please check the backup device"exit 3fi# end of unload在如上示例中出現了exit, exit有兩個作用:一是停止程式中其他命令的執行,二是設定程式的退出狀態g. if巢狀及elif結構if commandthencommandelseif commandthencommandelseif commandthencommandfififi改進:使用elif結構if commandthencommandelif commandthencommandelif commandthencommandfielif結構同if結構類似,但結構更清淅,其執行結果完全相同.h.互動式從鍵盤讀入資料使用read語句,其格式如下:read var1 var2 ... varnread將不作變數替換,但會刪除多餘的空格,直到遇到第一個換行符(回車),並將輸入值依次賦值給相應的變數。例:$ read var1 var2 var3Hello my friends$ echo $var1 $var2 $var3Hello my friends$ echo $var1Hello$ read var1 var2 var3Hello my dear friends$ echo $var3dear friends $ read var1 var2 var3Hello friends$ echo $var3$在shell script中可使用read語句進行互動操作:...#echo -n message 輸出結果後不換行echo -n "Do you want to continue: Y or N"read ANSWERif [ $ANSWER=N -o $ANSWER=n ]thenexitfii. case結構:結構較elif-then結構更清楚比較if-then語句:if [ variable1 = value1 ]thencommandcommandelif [ variable1 = value2 ]thencommandcommandelif [ variable1 = value3 ]thencommandcommandfi相應的case結構:case value inpattern1)commandcommand;;pattern2)commandcommand;;...patternn)command;esac* case語句只執行第一個匹配模式例:使用case語句建立一個選單選擇shell script#Display a menuecho _echo "1 Restore"echo "2 Backup"echo "3 Unload"echo#Read and excute the user's selectionecho -n "Enter Choice:"read CHOICEcase "$CHOICE" in1) echo "Restore";;2) echo "Backup";;3) echo "Unload";;*) echo "Sorry $CHOICE is not a valid choiceexit 1esac在上例中,*指預設匹配動作。此外,case模式中也可以使用邏輯操作,如下所示:pattern1 | pattern2 ) commandcommand ;;這樣可以將上面示例程式中允許使用者輸入數字或每一個大寫字母。case "$CHOICE" in1|R) echo "Restore";;2|B) echo "Backup";;3|U) echo "Unload";;*) echo "Sorry $CHOICE is not a valid choiceexit 1esac(5)迴圈控制<1> while迴圈:格式:while commanddocommandcommandcommand...done例: 計算1到5的平方#!/bin/sh##Filename: square.shint=1while [ $int -le 5 ]dosq=`expr $int * $int`echo $sqint=`expr $int + 1`doneecho "Job completed"$ sh square.sh1491625Job completed<2> until迴圈結構:格式:until commanddocommandcommand....commanddone示例:使用until結構計算1-5的平方#!/bin/shint=1until [ $int -gt 5 ]dosq=`expr $int * $int`echo $sqint=`expr $int + 1`doneecho "Job completed"<3> 使用shift對不定長的引數進行處理在以上的示例中我們總是假設命令列引數唯一或其個數固定,或者使用$*將整個命令行引數傳遞給shell script進行處理。對於引數個數不固定並且希望對每個命令引數進行單獨處理時則需要shift命令。使用shift可以將命令列位置引數依次移動位置,即$2->$1, $3->$2. 在移位之前的第一個位置引數$1在移位後將不在存在。示例如下:#!/bin/sh##Filename: shifteruntil [ $# -eq 0 ]doecho "Argument is $1 and `expr $# - 1` argument(s) remain"shiftdone$ shifter 1 2 3 4Argument is 1 and 3 argument(s) remainArgument is 2 and 2 argument(s) remainArgument is 3 and 1 argument(s) remainArgument is 4 and 0 argument(s) remain$使用shift時,每進行一次移位,$#減1,使用這一特性可以用until迴圈對每個參數進行處理,如下示例中是一個求整數和的shell script:#!/bin/sh# sumints - a program to sum a series of integers#if [ $# -eq 0 ]thenecho "Usage: sumints integer list"exit 1fisum=0until [ $# -eq 0 ]dosum=`expr $sum + $1`shiftdoneecho $sum$ sh sumints 324 34 34 12 34438$使用shift的另一個原因是Bourne Shell的位置引數變數為$1~$9, 因此透過位置變數只能訪問前9個引數。但這並不等於在命令列上最多隻能輸入9個引數。此時如果想訪問前9個引數之後的引數,就必須使用shift.另外shift後可加整數進行一次多個移位,如:shift 3<4>. for迴圈格式:for var in arg1 arg2 ... argndocommand....commanddone示例:$ for letter in a b c d e; do echo $letter;doneabcde對當前目錄下的所有檔案操作:$ for i in *doif [ -f $i ]thenecho "$i is a file"elif [ -d $i ]echo "$i is a directory"fidone求命令列上所有整數之和:#!/bin/shsum=0for INT in $*dosum=`expr $sum + $INT`doneecho $sum<6> 從迴圈中退出: break和continue命令break 立即退出迴圈continue 忽略本迴圈中的其他命令,繼續下一下迴圈在shell程式設計中有時我們要用到進行無限迴圈的技巧,也就是說這種迴圈一直執行碰到break或continue命令。這種無限迴圈通常是使用true或false命令開始的。UNIX系統中的true總是返加0值,而false則返回非零值。如下所示:#一直執行到程式執行了break或使用者強行中斷時才結束迴圈while truedocommand....commanddone上面所示的迴圈也可以使用until false, 如下:until falsedocommand....commanddone在如下shell script中同時使用了continue,break以及case語句中的正規表示式用法:#!/bin/sh# Interactive program to restore, backup, or unload# a directoryecho "Welcome to the menu driven Archive program"while truedo# Display a Menuechoecho "Make a Choice from the Menu below"echo _echo "1 Restore Archive"echo "2 Backup directory"echo "3 Unload directory"echo "4 Quit"echo# Read the user's selectionecho -n "Enter Choice: "read CHOICEcase $CHOICE in[1-3] ) echo# Read and validate the name of the directoryecho -n "What directory do you want? "read WORKDIRif [ ! -d "$WORKDIR" ]thenecho "Sorry, $WORKDIR is not a directory"continuefi# Make the directory the current working directorycd $WORKDIR;;4) :;; # :為空語句,不執行任何動作*) echo "Sorry, $CHOICE is not a valid choice"continueesaccase "$CHOICE" in1) echo "Restoring..."cpio -i2) echo "Archiving..."ls | cpio -o >/dev/rmt/0h;;3) echo "Unloading..."ls | cpio -o >/dev/rmt/0h;;4) echo "Quitting"break;;esac#Check for cpio errorsif [ $? -ne 0 ]thenecho "A problem has occurred during the process"if [ $CHOICE = 3 ]thenecho "The directory will not be erased"fiecho "Please check the device and try again"continueelseif [ $CHOICE = 3 ]thenrm *fifidone(6)結構化程式設計:定義函式同其他高階語言一樣,shell也提供了函式功能。函式通常也稱之為子過程(subroutine),其定義格式如下:funcname(){command...command; #分號}定義函式之後,可以在shell中對此函式進行呼叫,使用函式定義可以將一個複雜的程式分為多個可管理的程式段,如下所示:# start programsetup (){ command list ; }do_data (){ command list ; }cleanup (){ command list ; }errors (){ command list ; }setupdo_datacleanup# end program技巧:. 在對函式命名時最好能使用有含義的名字,即函式名能夠比較準確的描述函式所完成的任務。. 為了程式的維護方便,請儘可能使用註釋使用函式的另一個好處就是可以在一個程式中的不同地方執行相同的命令序列(函式),如下所示:iscontinue(){while truedoecho -n "Continue?(Y/N)"read ANSWERcase $ANSWER in[Yy]) return 0;;[Nn]) return 1;;*) echo "Answer Y or N";;esacdone}這樣可以在shell程式設計中呼叫iscontinue確定是否繼續執行:if iscontinuethencontinueelsebreakfi** shell函式與shell程式非常相似,但二者有一個非常重要的差別:shell程式是由子shell執行的,而shell函式則是作為當前shell的一部分被執行的,因此在當前shell中可以改變函式的定義。此外在任意shell(包括互動式的shell)中均可定義函式,如:$ dirdir: not found$ dir () { ls -l ;}$ dirtotal 5875-rw-r--r-- 1 hbwork 100 Nov 10 23:16 doc-rw-r--r-- 1 hbwork 2973806 Nov 10 23:47 ns40docs.zip-rw-r--r-- 1 hbwork 1715011 Nov 10 23:30 ns840usr.pdf-rw-r--r-- 1 hbwork 1273409 Sep 23 1998 radsol21b6.tar.Z-rw-r--r-- 1 hbwork 7526 Nov 10 23:47 wget-log-rw-r--r-- 1 hbwork 1748 Nov 13 21:51 wget-log.1$ unset dir$ dir () {> echo "Permission Link Owner Group File_SZ LastAccess FileName"> echo "-----------------------------------------------------------"> ls -l $*;> }$ dirPermission Link Owner Group File_SZ LastAccess FileName-----------------------------------------------------------total 5875-rw-r--r-- 1 hbwork 100 Nov 10 23:16 doc-rw-r--r-- 1 hbwork 2973806 Nov 10 23:47 ns40docs.zip-rw-r--r-- 1 hbwork 1715011 Nov 10 23:30 ns840usr.pdf-rw-r--r-- 1 hbwork 1273409 Sep 23 1998 radsol21b6.tar.Z-rw-r--r-- 1 hbwork 7526 Nov 10 23:47 wget-log-rw-r--r-- 1 hbwork 1748 Nov 13 21:51 wget-log.1通常情況下,shell script是在子shell中執行的,困此在此子shell中對變數所作的修改對父shell不起作用。點(.) 命令使用shell在不建立子shell而由當前shell讀取並執行一個shell script, 可以透過這種方式來定義函式及變數。此外點(.)命令最常用的功能就是透過讀取.profile來重新配置初始化login變數。如下所示:$ . .profile(csh相對於.命令的是source命令).(7)使用And/Or結構進行有條件的命令執行<1> And , 僅當第一個命令成功時才有執行後一個命令,如同在邏輯與表示式中如果前面的結果為真時才有必要繼續運算,否則結果肯定為假。格式如下:command1 && command2例:rm $TEMPDIR/* && echo "File successfully removed"等價於if rm $TEMPDIR/*thenecho "File successfully removed"fi<2>Or, 與AND相反,僅當前一個命令執行出錯時才執行後一條命令例: rm $TEMPDIR/* || echo "File not removed"等價與:if rm $TEMPDIR/*thencommandelseecho "File not removed"fi<3> 混合命令條件執行command1 && command2 && command3當command1, command2成功時才執行command3command1 && command2 || comamnd3僅當command1成功,command2失敗時才執行command3當然可以根據自己的需要進行多種條件命令的組合,在此不多講述。(8) 使用getopts命令讀取unix格式選項UNIX格式選項指如下格式的命令列引數:command -options parameters使用格式:getopts option_string variable具體使用方法請參考getopts的線上文件(man getopts).示例如下:#newdateif [ $# -lt 1 ]thendateelsewhile getopts mdyDHMSTjJwahr OPTIONdocase $OPTIONinm) date '+%m ';; # Month of Yeard) date '+%d ';; # Day of Monthy) date '+%y ';; # YearD) date '+%D ';; # MM/DD/YYH) date '+%H ';; # HourM) date '+%M ';; # MinuteS) date '+%S ';; # SecondT) date '+%T ';; # HH:MM:SSj) date '+%j ';; # day of yearJ) date '+%y%j ';;# 5 digit Julian datew) date '+%w ';; # Day of the Weeka) date '+%a ';; # Day abbreviationh) date '+%h ';; # Month abbreviationr) date '+%r ';; # AM-PM time?) echo "Invalid option $OPTION";;esacdonefi$ newdate -J94031$ newdate -a -h -dMonJan31$ newdate -ahdMonJan31$示例程式:複製程式# Syntax: duplicate [-c integer] [-v] filename# where integer is the number of duplicate copies# and -v is the verbose optionCOPIES=1VERBOSE=Nwhile getopts vc: OPTIONdocase $OPTIONinc) COPIES=$OPTARG;;v) VERBOSE=Y;;?) echo "Illegal Option"exit 1;;esacdoneif [ $OPTIND -gt $# ]thenecho "No file name specified"exit 2fishift `expr $OPTIND -1`FILE=$1COPY=0while [ $COPIES -gt $COPY ]doCOPY=`expr $COPY + 1`cp $FILE ${FILE}${COPY}if [ VERBOSE = Y ]thenecho ${FILE}${COPY}fidone$ duplicate -v fileAfileA1$ duplicate -c 3 -v fileBfileB1fileB2fileB34. Shell的定製通常使用shell的定製來控制使用者自己的環境,比如改變shell的外觀(提示符)以及增強自己的命令。(1)通常環境變數來定製shell通常改變環境變數可以定製shell的工作環境。shell在處理資訊時會參考這些環境變數,改變環境變數的值在一定程度上改變shell的操作方式,比如改變命令列提示符。.使用IFS增加命令列分隔符預設狀態下shell的分隔符為空格、製表符及換行符,但可以透過改變IFS的值加入自己的分隔符。如下所示:$ IFS=":"$ echo:Hello:my:FriendHello my Friend(2)加入自己的命令及函式如下程式:#Directory and Prompt change program#Syntax: chdir directoryif [ ! -d "$1" ]thenecho "$1 is not a directory"exit 1ficd $1PS1=`pwd`$export PS1$ chdir /usr/home/teresa$但此程式在執行時系統提示符並不會改變,因為此程式是在子shell中執行的。因此其變數對當前shell並無影響,要想對當前shell起作用,最好是將此作為函式寫在自己的.profile中或建立自己的個人函式檔案.persfuncs#Personal function file persfuncschdir(){#Directory and Prompt change program#Syntax: chdir directoryif [ ! -d "$1" ]thenecho "$1 is not a directory"exit 1ficd $1PS1=`pwd`$export PS1;}再執行:$ . .persfuncs$ chdir temp/home/hbbwork/temp$也可在自己的.profile檔案中用 . .persfuncs呼叫.persfuncs.說明:在bash/tcsh中已經使用別名,相對而言別名比此方法更為方便。5. 有關shell的專門討論(1)shell程式的除錯切記:程式設計師(人)總是會犯錯誤的,而計算機是不會錯的。使用-x進行跟蹤執行,執行並顯示每一條指令。(2)命令組用小括號將一組命令括起來,則這些命令會由子shell來完成;而{command_list;}則在當前shell中執行。這兩者的主要區別在於其對shell變數的影響,子shell執行的命令不會影響當前shell中的變數。$ NUMBER=2$ (A=2;B=2;NUMBER=`expr $A + $B`; echo $NUMBER)4$ echo $NUMBER2$ { A=2;B=2;NUMBER=`expr $A + $B`; echo $NUMBER; }4$ echo $NUMBER4總結:在本章中講述了Bourne Shell的基本知識,使用shell變數,shell script基礎。這些概念對於理解學習Korn Shell, csh以及其他script程式設計都是非常有用的。很多OS都有不少語言及一些script功能,但很少有象UNIX SHELL這樣靈活強大的script腳本語言能力。對於系統管理員或程式設計師來說,熟練地使用shell script將對日常工作(系統維護及管理)非常有用,如果你想作一個合格的系統管理員,強烈建議你進一步深入的瞭解和使用shell.另外,對於系統管理員來說,PERL也是一個必不可少的script程式語言,尤其是對於處理文字格式的各種檔案,PERL具有shell, awk, sed, grep等的功能,但使用起來更為靈活,功能也更強大。大家可以參考“Perl By Examples"來學習和使用PERL。made by pageshop of CERNET network centre of DaLian region.copyright 199
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/8225414/viewspace-944881/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- shell程式設計(轉)程式設計
- Bourne shell script中的quoting
- Shell程式設計 --- Shell介紹程式設計
- shell程式設計幫助(轉)程式設計
- Linux 程式設計之Shell程式設計(轉)Linux程式設計
- shell程式設計程式設計
- Shell程式設計-shell變數1程式設計變數
- BASH SHELL 程式設計簡介(轉)程式設計
- Linux Shell程式設計(1)——shell程式設計簡介Linux程式設計
- Shell程式設計-11-子Shell和Shell巢狀程式設計巢狀
- Shell程式設計-02-Shell變數程式設計變數
- Linux Shell程式設計(27)——子shellLinux程式設計
- Windows Shell 程式設計Windows程式設計
- shell程式設計二程式設計
- shell程式設計五程式設計
- BASH Shell的指令碼程式設計(轉)指令碼程式設計
- Linux的shell程式設計(一)(轉)Linux程式設計
- Linux的shell程式設計(二)(轉)Linux程式設計
- Linux的shell程式設計(三)(轉)Linux程式設計
- Linux的shell程式設計(四)(轉)Linux程式設計
- Linux Shell程式設計(2)——第一個shell程式Linux程式設計
- 玩轉Linux – shell 程式設計基礎Linux程式設計
- 幾個shell程式設計小知識(轉)程式設計
- 初識shell程式設計程式設計
- Shell 程式設計入門程式設計
- shell程式設計進階程式設計
- shell程式設計入門程式設計
- Shell程式設計-基礎程式設計
- shell併發程式設計程式設計
- linux shell 程式設計Linux程式設計
- linux shell程式設計Linux程式設計
- 戀上shell程式設計程式設計
- Oracle-SHELL程式設計Oracle程式設計
- shell程式設計簡介程式設計
- shell vbscript xml程式設計XML程式設計
- shell程式設計基礎程式設計
- shell 程式設計簡記程式設計
- Shell程式設計-09-Shell中的函式程式設計函式