1. 函数创建与使用
创建格式:
function name { name() {
commands 或 commands
} }
调用: 直接写函数名就可以调用
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 [Hermioner@localhost Documents]$ cat test2.sh 2 #!/bin/bash 3 func1() { 4 lss 5 echo "hello" 6 } 7 func1 8 echo $? 9 [Hermioner@localhost Documents]$ bash test2.sh 10 test2.sh: line 3: lss: command not found 11 hello 12 0 13 [Hermioner@localhost Documents]$
note:用标准变量$?来确定函数的退出状态码,它默认是返回的是函数中的最后一条命令的退出状态码,即使函数中间有错误。----------很危险
可以有两种办法来改进:return 和使用函数输出
(1)使用return命令
函数调用和状态码输出语句中什么别的语句都不添加的话,函数调用的返回结果将代替状态码中的值,否则,就会返回最后一条语句的状态码。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 [Hermioner@localhost Documents]$ cat test1.sh 2 #!/bin/bash 3 function f1 { 4 read -p "Please enter a value:" value 5 echo "double the value" 6 return $[ $value*2 ] 7 } 8 9 f1 10 11 echo "The new value is $?" 12 [Hermioner@localhost Documents]$ bash test1.sh 13 Please enter a value:3 14 double the value 15 The new value is 6 16 [Hermioner@localhost Documents]$ bash test1.sh 17 Please enter a value:200 18 double the value 19 The new value is 144 20 [Hermioner@localhost Documents]$ 21 #这种情况函数的返回值作为$?的值,但是任何大于256的值都会产生一个错误的值,函数的返回值不可以大于256.因为退出状态码的值必须是0-255.
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 [Hermioner@localhost Documents]$ cat test1.sh 2 #!/bin/bash 3 function f1 { 4 read -p "Please enter a value:" value 5 echo "double the value" 6 return $[ $value*2 ] 7 } 8 9 f1 10 echo "hello" 11 echo "The new value is $?" 12 [Hermioner@localhost Documents]$ bash test1.sh 13 Please enter a value:3 14 double the value 15 hello 16 The new value is 0 17 #这种情况是函数的返回值并没有在$?显示出来
(2)使用函数输出----整数,浮点,字符串都适用
可以将函数的输出保存在变量中。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 [Hermioner@localhost Documents]$ cat test2.sh 2 #!/bin/bash 3 function f2 { 4 read -p "Pleas enter a value: " value 5 echo $[ $value*2 ] 6 } 7 result=$(f2) 8 echo "The reuslt is $result" 9 [Hermioner@localhost Documents]$ bash test2.sh 10 Pleas enter a value: 3 11 The reuslt is 6 12 [Hermioner@localhost Documents]$
2. 在函数中使用变量
(1)向函数传递参数
在脚本中指定函数时,必须将参数和函数放在同一行。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 [Hermioner@localhost Documents]$ cat test1.sh 2 #!/bin/bash 3 function f1 { 4 echo $1 5 } 6 #value=$(f1 $1) 7 value=$(f1) 8 echo "the new value is $value" 9 10 11 [Hermioner@localhost Documents]$ bash test1.sh 12 the new value is 13 [Hermioner@localhost Documents]$ bash test1.sh 3 14 the new value is 15 #脚本中在调用函数时没有使用$1
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 [Hermioner@localhost Documents]$ cat test1.sh 2 #!/bin/bash 3 function f1 { 4 echo $1 5 } 6 value=$(f1 $1) 7 #value=$(f1) 8 echo "the new value is $value" 9 10 11 [Hermioner@localhost Documents]$ bash test1.sh 12 the new value is 13 [Hermioner@localhost Documents]$ bash test1.sh 3 14 the new value is 3 15 #在函数调用时采用了$1传入参数
note:必须在脚本中也手动传参
(2)在函数中处理变量
全局变量和局部变量的处理。在函数内部变量或者变量赋值前面写上local,就可以当作局部变量处理,否则,默认当成全局变量处理。
全局变量在shell脚本中任何地方都是有效的变量。如果你在脚本的主体部分定义了一个全局变量,那么可以在函数内读取它的值。类似地,如果你在函数内定义了一个全局变量,可以在脚本的主体部分读取它的值。
默认情况下,你在脚本中定义的任何变量都是全局变量。在函数外定义的变量可以在函数内正常访问。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 [Hermioner@localhost Documents]$ cat htest.sh 2 #!/bin/bash 3 function f1{ 4 temp=$[ $value + 5 ] 5 result=$[ $temp * 2 ] 6 } 7 temp=4 8 value=6 9 f1 10 echo "The result is $result" 11 if [ $temp -gt $value ] 12 then 13 echo "temp is larger" 14 else 15 echo "temp is smaller" 16 fi 17 18 19 ./htest.sh 20 The result is 22 21 temp is larger 22 如果在temp前面加了local,输出为: 23 The result is 22 24 temp is smaller
3. 数组变量和函数
(1)向函数传数组参数
类似变量传入
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 [Hermioner@localhost Documents]$ cat test1.sh 2 #!/bin/bash 3 function f1 { 4 local newarry 5 newarry=(echo $@) 6 echo "The new arry value is: ${newarry[*]}" 7 } 8 myarry=(1 2 3 4 5) 9 echo "The original array is ${myarry[*]}" 10 #f1 ${myarry[*]} 11 f1 $myarry 12 [Hermioner@localhost Documents]$ bash test1.sh 13 The original array is 1 2 3 4 5 14 The new arry value is: echo 1 15 [Hermioner@localhost Documents]$
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 [Hermioner@localhost Documents]$ cat test1.sh 2 #!/bin/bash 3 function f1 { 4 local newarry 5 newarry=(echo $@) 6 echo "The new arry value is: ${newarry[*]}" 7 } 8 myarry=(1 2 3 4 5) 9 echo "The original array is ${myarry[*]}" 10 f1 ${myarry[*]} 11 #f1 $myarry 12 [Hermioner@localhost Documents]$ bash test1.sh 13 The original array is 1 2 3 4 5 14 The new arry value is: echo 1 2 3 4 5 15 [Hermioner@localhost Documents]$
(2)从函数返回数组
参考博客: https://blog.csdn.net/guizaijianchic/article/details/78012179
4. 函数递归
比如计算4的阶乘 x!=x*(x-1)!
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 [Hermioner@localhost Documents]$ cat test1.sh 2 #!/bin/bash 3 function f { 4 if [ $1 -eq 1 ] 5 then 6 echo 1 7 else 8 local temp=$[ $1-1 ] 9 local result=$(f $temp) 10 echo $[ $result*$1 ] 11 fi 12 } 13 read -p "Please enter a value: " value 14 result=$(f $value) 15 echo "The final result is: $result" 16 [Hermioner@localhost Documents]$ bash test1.sh 17 Please enter a value: 4 18 The final result is: 24 19 [Hermioner@localhost Documents]$
5. 创建库
将常用的函数定义成库函数,这样在不同的目录下可以调用这个函数。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 [Hermioner@localhost ~]$ bash testfile 2 the result is 25 3 [Hermioner@localhost ~]$ cat testfile 4 #!/bin/bash 5 source /home/Hermioner/Documents/myfuncs 6 result=$(addem 10 15) 7 echo "the result is $result"
其中的source可以用点号代替。注意路径一定要对。
note:也可以在命令行上创建函数,但是一旦退出shell,这个函数就消失了。为了避免这个缺点,可以在.bashrc文件中来自定义库函数。但是这个文件中已经又发行版本定义好的库函数,小心操作。
参考文献:
Linux命令行与shell脚本编程大全(第3版)[美] 布鲁姆(Richard Blum),布雷斯纳汉(Christine Bresnahan) 著,门佳,武海峰 译