===================================================== ======================= ==== Shell函数 ====== ======================= shell允许将一组命令集或语句形成一个可用块,这些块称为shell函数 函数有两部分组成:函数标题和函数休 标题是函数名。函数休是函数内的命令集合。标题名应该唯一;如果不是,将会混淆结果 定义函数的格式为: =============================== 函数名() { 命令1 ... } 或者 函数名() { 命令1 ... } =============================== 也可以在函数名前加上关键字function,例 function 函数名() { .... } 可以将函数看作是脚本中的一段代码,但是有一个主要区别。执行函数时,它保留当前shell和内存 信息。此外如果执行或调用一个脚本文件中的另一段代码,将创建一个单独的shell,因而去除所有 原脚本中定义的存在变量。 函数可以放在同一个文件中作为一段代码,也可以放在只包含函数的单独文件中。函数不必包含很多 语句或命令,甚至可以只包含一个echo语句,这取决于使用者 在脚本中定义函数 以下是一个简单函数 hello () { echo "Hello there today's date is `date`" } 所有函数在使用前必须定义。这意味着必须将函数放在脚本开始部分,直到shell解释器首次发现它时 才可以使用。调用函数仅使用其函数名即可。上面的例子中,函数名为hello,函数休包含一个echo 语句,反馈当天日期 在脚本中使用函数 #!/bin/bash #ScriptName func1 hello () { 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 创建一个函数文件: ############################# #!/bin/bash #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 () { if [ $# -lt 1 ]; then echo "Usage: findit file"; return 1; fi; find / -name $1 -print } 载入成功后就可以直接输入函数名来执行函数了 [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 ========================================================== #!/bin/bash #ScriptName char_name char_name() { _LETTERS_ONLY=$1 _LETTERS_ONLY=`echo $1 | awk '{if ($0~/[^a-zA-Z]/) print "1"}'` if [ "$_LETTERS_ONLY" != "" ]; then return 1 else return 0 fi } 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 else name_error $F_NAME fi done while : do echo -n "What is your surname :" read S_NAME if char_name $S_NAME; then break else name_error $S_NAME fi done ===================================================== 以上脚本定义了两个函数,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,才会结束循环 下面的就一样了,不多解释。 ================================================================= #!/bin/bash #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的变量。就是只允许用户输入一个字母,然后自动把这个字母传给变量。
#!/bin/bash
months()
{
_MONTH=$1
if [ $# -ne 1 ]; then
echo "months: I need a number 1 to 12"
return 1
fi
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"
return 1
;;
esac
echo $_FULL
}
months $1
本文转自 gm100861 51CTO博客,原文链接:http://blog.51cto.com/gm100861/789376