首页 > 代码库 > SHELL笔记8
SHELL笔记8
函数,就是一个命令或者一组命令的名字。
函数可以使程序模块化,从而提高效率。
shell将函数存放在内存中而不是磁盘文件中,所以访问函数的速度要比访问脚本的速度快得多。
shell对函数进行预处理,因此,启动速度较快。
使用一个函数之前,必须先在程序中创建该函数。
创建一个函数也称定义函数或函数的声明。
[function] 函数名 { 命令表 [return] }
其中:
(1)关键字function表示定义一个函数,可以省略,其后是“函数名”。(函数名称后面可以加一对空的括号)
(2)函数中的return用于返回函数中最后一个命令的退出状态值或者给定的参数值。
(3)如果在函数中使用exit命令,则可以退出整个脚本。 如果函数退出,就返回到脚本中调用该函数的地方。
(4)可以使用break语句来中断函数的执行。
(5)使用内部命令declare -f可以显示定义的函数清单。 如果只显示函数的名字,可以用命令declare -F。
(6)可以使用命令export -f将函数输出给shell
(7)可能使用命令unset -f从shell内存中删除函数
函数定义位置:可以放在~/.bash_profile文件中,或者放在使用该函数的脚本中,也可以直接放在命令行中。
函数的删除:可以使用unset命令删除删除;一旦用户注销,shell将不再保持这些函数。
函数的调用,涉及 函数的执行、函数参数传递、函数返回值、载入函数以及函数的删除。 函数被执行前,必须首先定义。
执行函数
shell在执行一个别名、函数、内部命令,或是一个基于磁盘的可执行文件时,总是先执行别名,然后是函数、内部命令,最后才是可执行程序。
执行函数,只需要直接输入函数名即可。
示例
1 #! /bin/bash 2 #filename a.sh 3 function show() 4 { 5 date 6 echo "the logname:" 7 echo $LOGNAME 8 } 9 show
通过命令行创建的函数,在用户退出登录时将自动删除。
函数参数传递
函数参数可以通过位置变量来传递。
在调用函数的命令行中,参数的位置定义如下所示
$函数名 参数1 参数2 参数3 ...
1 #! /bin/bash 2 #filename a.sh 3 function show() 4 { 5 echo $a $b $b $c $d 6 echo $1 $2 $3 $4 7 } 8 a=111 9 b=222 10 c=333 11 d=444 12 echo "Function Begin" 13 show a b c d 14 echo "Function End"
# bash a.sh Function Begin 111 222 222 333 444 a b c d Function End
1 #! /bin/bash 2 #filename a.sh 3 cube() 4 { 5 ITEM=`expr $1 \* $1 \* $1` 6 } 7 8 echo "Please enter a integer: " 9 read N 10 i=1 11 RESULT=0 12 ITEM= 13 while [ $i -le $N ] 14 do 15 cube $i 16 RESULT=`expr $RESULT + $ITEM` 17 i=$(($i+1)) 18 done 19 echo "compute 1...$N de li fang he is : $RESULT" 注:不能随意的添加空格;ITEM后面、=前后,不要随意加空格
函数的返回值
函数中的关键字return,可以放在函数体的任意位置,通常用于返回某些值。
程序在执行到return之后,函数就停止往下执行,返回到主程序的调用行。
返回值,0~256之间的一个整数。 返回值将保存到变量$?中。
如果没有指定return的返回值,则返回的函数值就是该函数中最后一个被执行的命令的退出状态值。
载入函数
函数的定义,可以放在~/.bash_profile文件中,或者直接放在命令行中,也可以放在脚本文件中。
如果需要使用的函数保存在其他的脚本文件中,可以通过source命令或.命令把它们装入到内存中,以供当前脚本使用。
local temp 定义本地变量
如下所示,分为两个文件a.sh和a1.sh。 在a1.sh中,使用source a.sh调用a.sh。
1 #! /bin/bash 2 #filename:a.sh 3 4 function square 5 { 6 local temp 7 let temp=$1*$1 8 echo "$1 square : $temp" 9 } 10 11 function cube 12 { 13 local temp 14 let temp=$1*$1*$1 15 echo "$1 cube : $temp" 16 } 1 #! /bin/bash 2 #filename:a1.sh 3 source a.sh 4 echo "Please enter an integer:" 5 read N 6 i=1 7 while [ $i -le $N ] 8 do 9 square $i 10 i=$(($i+1)) 11 done 12 echo "------------------" 13 i=1 14 while [ $i -le $N ] 15 do 16 cube $i 17 i=$(($i+1)) 18 done # bash a1.sh Please enter an integer: 3 1 square : 1 2 square : 4 3 square : 9 ------------------ 1 cube : 1 2 cube : 8 3 cube : 27 #
删除函数
unset -f命令,从shell内存中删除函数: unset -f 函数名
declare -f显示内存中已定义的函数
函数作用域
作用域,即变量的作用范围。 作用域,定义了变量的可见性和生命周期。
全局作用域
(1)函数在当前环境下运行,跟调用它的脚本分享变量,即无论在函数内外,没有使用关键字local进行特别声明的变量都具有全局作用域。
(2)全局变量可以在程序的任何地方被访问。
局部作用域
(1)在函数中使用关键字local声明的变量称为该函数的局部变量。
(2)局部变量的作用域局限在函数内。
(3)当在局部变量之外输出局部变量时,输出为空。
当全局作用域与局部作用域发生重叠时,按就近原则处理。
shell支持函数的嵌套,即在函数中定义并调用其他函数
函数的递归
递归,是指用自己的定义来说明自己。
递归函数,特别适用于浏览动态数据结构,如列表和树。
为了避免死循环, 在设计递归函数的时候,必须有一个明确的且必定会发生的条件来终止函数的递归调用。
很多情况下,递归可以用循环来取代,因为两者都是做一些重复的事情。
递归调用,比循环慢,而且占用更多的内存,所以应该尽量用循环。
示例
1 #! /bin/bash 2 #filename:a.sh 3 function reverse 4 { 5 local t 6 echo $1 7 if [ $1 -gt 0 ]; then 8 t=$(($1-1)) 9 reverse $t 10 fi 11 } 12 13 reverse 10
SHELL笔记8