執行個體
一般編程步驟
現在我們來討論編寫一個指令碼的一般步驟。任何優秀的指令碼都應該具有協助和輸入參數。並且寫一個偽指令碼(framework.sh),該指令碼包含了大多數指令碼都需要的架構結構,是一個非常不錯的主意。這時候,在寫一個新的指令碼時我們只需要執行一下copy命令:
cpframework.shmyscript
然後再插入自己的函數。
讓我們再看兩個例子:
二進位到十進位的轉換
指令碼b2d將位元(比如1101)轉換為相應的十進位數。這也是一個用expr命令進行數學運算的例子:
#!/bin/sh
#vim:setsw=4ts=4et:
help()
{
cat
USAGE:b2h[-h]binarynum
OPTIONS:-hhelptext
EXAMPLE:b2h111010
willreturn58
HELP
exit0
}
error()
{
#printanerrorandexit
echo"$1"
exit1
}
lastchar()
{
#returnthelastcharacterofastringin$rval
if[-z"$1"];then
#emptystring
rval=""
return
fi
#wcputssomespacebehindtheoutputthisiswhyweneedsed:
numofchar=`echo-n"$1"|wc-c|sed's///g'`
#nowcutoutthelastchar
rval=`echo-n"$1"|cut-b$numofchar`
}
chop()
{
#removethelastcharacterinstringandreturnitin$rval
if[-z"$1"];then
#emptystring
rval=""
return
fi
#wcputssomespacebehindtheoutputthisiswhyweneedsed:
numofchar=`echo-n"$1"|wc-c|sed's///g'`
if["$numofchar"="1"];then
#onlyonecharinstring
rval=""
return
fi
numofcharminus1=`expr$numofchar"-"1`
#nowcutallbutthelastchar:
rval=`echo-n"$1"|cut-b0-${numofcharminus1}`
}
while[-n"$1"];do
case$1in
-h)help;shift1;;#functionhelpiscalled
--)shift;break;;#endofoptions
-*)error"error:nosuchoption$1.-hforhelp";;
*)break;;
esac
done
#Themainprogram
sum=0
weight=1
#oneargmustbegiven:
[-z"$1"]&&help
binnum="$1"
binnumorig="$1"
while[-n"$binnum"];do
lastchar"$binnum"
if["$rval"="1"];then
sum=`expr"$weight"" ""$sum"`
fi
#removethelastpositionin$binnum
chop"$binnum"
binnum="$rval"
weight=`expr"$weight""*"2`
done
echo"binary$binnumorigisdecimal$sum"
#
該指令碼使用的演算法是利用十進位和位元權值(1,2,4,8,16,..),比如二進位"10"可以這樣轉換成十進位:
0*1 1*2=2
為了得到單個的位元我們是用了lastchar函數。該函數使用wc–c計算字元個數,然後使用cut命令取出末尾一個字元。Chop函數的功能則是移除最後一個字元。
檔案迴圈程式
或許您是想將所有發出的郵件儲存到一個檔案中的人們中的一員,但是在過了幾個月以後,這個檔案可能會變得很大以至於使對該檔案的訪問速度變慢。下面的指令碼rotatefile可以解決這個問題。這個指令碼可以重新命名郵件儲存檔案(假設為outmail)為outmail.1,而對於outmail.1就變成了outmail.2等等等等...
#!/bin/sh
#vim:setsw=4ts=4et:
ver="0.1"
help()
{
cat
USAGE:rotatefile[-h]filename
OPTIONS:-hhelptext
EXAMPLE:rotatefileout
Thiswille.grenameout.2toout.3,out.1toout.2,outtoout.1
andcreateanemptyout-file
Themaxnumberis10
version$ver
HELP
exit0
}
error()
{
echo"$1"
exit1
}
while[-n"$1"];do
case$1in
-h)help;shift1;;
--)break;;
-*)echo"error:nosuchoption$1.-hforhelp";exit1;;
*)break;;
esac
done
#inputcheck:
if[-z"$1"];then
error"ERROR:youmustspecifyafile,use-hforhelp"
fi
filen="$1"
#renameany.1,.2etcfile:
fornin987654321;do
if[-f"$filen.$n"];then
p=`expr$n 1`
echo"mv$filen.$n$filen.$p"
mv$filen.$n$filen.$p
fi
done
#renametheoriginalfile:
if[-f"$filen"];then
echo"mv$filen$filen.1"
mv$filen$filen.1
fi
echotouch$filen
touch$filen
這個指令碼是如何工作的呢?在檢測使用者提供了一個檔案名稱以後,我們進行一個9到1的迴圈。檔案9被命名為10,檔案8重新命名為9等等。迴圈完成之後,我們將原始檔案命名為檔案1同時建立一個與原始檔案同名的空檔案。
調試
最簡單的調試命令當然是使用echo命令。您可以使用echo在任何懷疑出錯的地方列印任何變數值。這也是絕大多數的shell程式員要花費80的時間來偵錯工具的原因。Shell程式的好處在於不需要重新編譯,插入一個echo命令也不需要多少時間。
shell也有一個真實的偵錯模式。如果在指令碼"strangescript"中有錯誤,您可以這樣來進行調試:
sh-xstrangescript
這將執行該指令碼並顯示所有變數的值。
shell還有一個不需要執行指令碼只是檢查文法的模式。可以這樣使用:
sh-nyour_script
這將返回所有語法錯誤。
我們希望您現在可以開始寫您自己的shell指令碼,希望您玩得開心。