天天看點

簡單介紹shell的函數

=====================================================

=======================

==== 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