=====================================================
=======================
==== Shell函數 ======
shell允許将一組指令集或語句形成一個可用塊,這些塊稱為shell函數
函數有兩部分組成:函數标題和函數休
标題是函數名。函數休是函數内的指令集合。标題名應該唯一;如果不是,将會混淆結果
定義函數的格式為:
===============================
函數名()
{
指令1
...
}
或者
函數名() {
也可以在函數名前加上關鍵字function,例
function 函數名()
....
可以将函數看作是腳本中的一段代碼,但是有一個主要差別。執行函數時,它保留目前shell和記憶體
資訊。此外如果執行或調用一個腳本檔案中的另一段代碼,将建立一個單獨的shell,因而去除所有
原腳本中定義的存在變量。
函數可以放在同一個檔案中作為一段代碼,也可以放在隻包含函數的單獨檔案中。函數不必包含很多
語句或指令,甚至可以隻包含一個echo語句,這取決于使用者
在腳本中定義函數
以下是一個簡單函數
hello ()
echo "Hello there today's date is `date`"
所有函數在使用前必須定義。這意味着必須将函數放在腳本開始部分,直到shell解釋器首次發現它時
才可以使用。調用函數僅使用其函數名即可。上面的例子中,函數名為hello,函數休包含一個echo
語句,回報當天日期
在腳本中使用函數
#!/bin/bash
#ScriptName func1
echo "Hello there today's date is `date +%Y-%m-%d`"
echo "Now,going to the function hello."
hello
echo "Back from the function"
向函數傳遞參數
向函數傳遞參數就像在一般腳本中使用特殊變量$1,$2...$9一樣,函數取得所傳參數後,将原始參數傳回
shell腳本,是以最好先在函數内重新設定變量儲存所傳的參數。這樣如果函數有一點錯誤,就可以通過
已經本地化的變量名迅速加以跟蹤。函數裡調用參數(變量)的轉換以下劃線開始。後加變量名
如: _FILENAME或_filename
建立一個函數檔案:
#############################
#FunctionFileName functions.main
findit ()
if [ $# -lt 1 ]; then
echo "Usage: findit file"
return 1
fi
find / -name $1 -print
函數檔案的開頭,跟Shell腳本是一樣的。函數檔案建立完成了。下面把它載入到shell
載入的方法跟把shell腳本裡的變量載入到shell裡方法是一樣的,可以使用
source FunctionFileName或者. FunctionFileName
載入完成後,可以使用set檢視。
USER=root
_=functions.main
consoletype=pty
qt_prefix=/usr/lib/qt-3.3
tmpid=0
findit ()
{
echo "Usage: findit file";
return 1;
fi;
載入成功後就可以直接輸入函數名來執行函數了
[root@localhost Shell]# findit httpd.conf
/etc/httpd/conf/httpd.conf
/usr/local/apache2/conf/httpd.conf
/usr/local/apache2/conf/original/httpd.conf
如果要删除函數,可以使用如下指令
unset function_name
==========================================================
#ScriptName char_name
char_name()
_LETTERS_ONLY=$1
_LETTERS_ONLY=`echo $1 | awk '{if ($0~/[^a-zA-Z]/) print "1"}'`
if [ "$_LETTERS_ONLY" != "" ]; then
else
return 0
name_error ()
echo "$@ contains errors, it must contain only letters"
while :
do
echo -n "What is your first name :"
read F_NAME
if char_name $F_NAME; then
break
name_error $F_NAME
done
echo -n "What is your surname :"
read S_NAME
if char_name $S_NAME; then
name_error $S_NAME
以上腳本定義了兩個函數,char_name用于判斷使用者輸入的内容是不是字母
awk '{if ($0~/[^a-zA-Z]/) print "1"}'如果不是大寫,也不是小寫,那麼傳回1[^]意思是不比對。下面的if
接着判斷,如果傳回非空,就是有内容,那麼就有錯誤,如果上面的指令執行成功,應該是沒内容傳回的。下面的
name_error是如果出現錯誤,則可以調用這個函數處理。下面進入到while判斷,while什麼也不做,然後提示使用者
輸入名字,然後用if判斷,如果函數char_name被正确執行,那麼則break,然後到下面的done,結束。如果不正确
則調用函數name_error的資訊,然後,錯誤的話,while會被繼續循環,因為隻有正确的情況下while,才會結束循環
下面的就一樣了,不多解釋。
=================================================================
#ScriptName
read_a_char()
SAVEDSTTY=`stty -g`
stty cbreak
dd if=/dev/tty bs=1 count=1 2>/dev/null
stty -cbreak
stty=$SAVEDSTTY
echo "Hit Any Key To Continue"
character=`read_a_char`
echo "In case you are wondering you pressed $character"
===========================================================
stty cbreak 就是開啟輸入立即響應模式,平時你read時,得用回車結束,這時預設按下一個鍵就響應,
例如按下"a"鍵後,立即将"a"送給read的變量。就是隻允許使用者輸入一個字母,然後自動把這個字母傳給變量。
months()
_MONTH=$1
if [ $# -ne 1 ]; then
echo "months: I need a number 1 to 12"
case $_MONTH in
1|01|Jan|jan)_FULL="January";;
2|02|Feb|feb)_FULL="February";;
3|03|Mar|mar)_FULL="March";;
4|04|Apr|apr)_FULL="April";;
5|05|May|may)_FULL="May";;
6|06|Jun|jun)_FULL="June";;
7|07|Jul|jul)_FULL="july";;
8|08|Aug|aug)_FULL="August";;
9|09|Sep|sep)_FULL="September";;
10|Oct|oct)_FULL="October";;
11|Nov|nov)_FULL="November";;
12|Dec|dec)_FULL="December";;
*) echo "Months:Unkown month"
;;
esac
echo $_FULL
months $1
本文轉自 gm100861 51CTO部落格,原文連結:http://blog.51cto.com/gm100861/789376