时间:2017年10月09日星期一
说明:本文部分内容均摘取自书籍《Linux命令行与shell脚本编程大全》,版权归原作者所有。《Linux命令行与shell脚本编程大全》(第三版)第十七章学习总结
第十七章:创建函数
本章内容
基本的脚本函数
返回值
在函数中使用变量
属组变量和函数
函数递归
创建库
在命令行上使用函数
17.1 基本的脚本函数
17.1.1 创建函数
格式一
function name{
commands
}
格式二
name(){
commands
}
说明
name属性定义了赋予函数的唯一名称
commands是构成函数的一条或多条bash shell命令
17.1.2 使用函数
编写test1.sh脚本
#!/bin/bash
function func1 {
echo "This is an example of a function"
}
count=1
while [ $count -le 5 ]
do
func1
count=$[ $count + 1 ]
done
echo "This is the end of the loop"
func1
echo "Now this is the end of the script"
函数需先定义,再使用
编写test2.sh脚本
#!/bin/bash
count=1
echo "This line comes before the function definition"
function func1 {
echo "This is an example of a function"
}
while [ $count -le 5 ]
do
func1
count=$[ $count + 1 ]
done
echo "This is the end of the loop"
func2
echo "Now this is the end of the script"
function func2 {
echo "This is an example of a function"
}
函数名必须唯一,否则新定义的函数会覆盖原来函数
编写test3.sh脚本
#!/bin/bash
function func1 {
echo "This is the first definition of the function name"
}
func1
function func1 {
echo "This is a repeat of the same function name"
}
func1
echo "This is the end of the script"
17.2 返回值
bash shell会把函数当做一个小型脚本,运行结束时会返回一个退出状态码
17.2.1 默认退出状态码
默认情况下,函数的退出状态码时函数中最后一条命令返回的退出状态码
在函数执行后,可以用标准变量$?来确定函数的退出状态码
只能判断函数中最后一条命令是否运行成功,无法判断函数中其它命令
使用函数的默认退出状态码时很危险的
编写test4.sh脚本
#!/bin/bash
func1() {
echo "trying to display a non-existent file"
ls -l badfile
}
echo "testing the function:"
func1
echo "The exit status is: $?"
17.2.2 使用return命令
使用return命令来退出函数并返回指定一个整数值的退出状态码
函数一结束就去返回值
退出状态码必须时0~255
编写test5.sh脚本
#!/bin/bash
function db1 {
read -p "Enter a value: " value
echo "doubling the value"
return $[ $value * 2 ]
}
db1
echo "The new value is $?"
17.2.3 使用函数输出
可以将函数的输出保存到变量中
编写test5b.sh脚本
#!/bin/bash
function db1 {
read -p "Enter a value: " value
echo $[ $value *2 ]
}
result=$(db1)
echo "The new value is $result"
17.3 在函数中使用变量
17.3.1 向函数传递参数
函数可以使用标准的参数环境变量来表示命令行上传给函数的参数。
例如,函数名会在$0变量中定义,函数命令行上的任何参数都会通过$1、$2等定义。
也可以用特殊变量$#来判断传给函数的参数数目。
在脚本中指定函数时,必须将参数和函数放在同一行
编写test6.sh脚本
#!/bin/bash
function addem {
if [ $# -eq 0 ] || [ $# -gt 2 ]
then
echo -1
elif [ $# -eq 1 ]
then
echo $[ $1 + $1 ]
else
echo $[ $1 + $2 ]
fi
}
echo -n "Adding 10 and 15:"
value=$(addem 10 15)
echo $value
echo -n "Let's try adding just one number:"
value=$(addem 10)
echo $value
echo -n "Now trying adding no numbers:"
value=$(addem)
echo $value
echo -n "Finally, try adding three numbers:"
value=$(addem 10 15 200)
echo $value
将传递给脚本的变量传给函数
编写test7.sh脚本
#!/bin/bash
function func7 {
echo $[ $1 * $2 ]
}
if [ $# -eq 2 ]
then
value=$(func7 $1 $2)
echo "The result is $value"
else
echo "Usage: test7 a b"
fi
17.3.2 在函数中处理变量
1.全局变量
全局变量是在shell脚本中任何地方都有效的变量。
如果你在脚本的主体部分定义了一个全局变量,那么可以在函数内读取它的值。
如果你在函数内定义了一个全局变量,可以在脚本的主题部分读取它的值。
默认情况下,在脚本中定义的任何变量都是全局变量,在函数外定义的变量可以在函数内访问。
编写test8.sh脚本
#!/bin/bash
function db1 {
value=$[ $value * 2 ]
}
read -p "Enter a value: " value
db1
echo "The new value is: $value"
2.局部变量
无需在函数中使用全局变量,函数内部使用的任何变量都可以被声明成局部变量。
在变量声明的前面加上local关键字即可。
也可以在变量赋值语句中使用local关键字。
编写test9.sh脚本
#!/bin/bash
function func1 {
local temp=$[ $value + 5 ]
result=$[ $temp * 2 ]
}
temp=4
value=6
func1
echo "The result is $result"
if [ $temp -gt $value ]
then
echo "temp is larger"
else
echo "temp is smaller"
fi
17.4 数组变量和函数
17.4.1 向函数传数组参数
将数组的值分解成单个的值作为函数参数使用
编写test10.sh脚本
#!/bin/bash
function testit {
local newarray
newarray=($@)
echo "The new array value is: ${newarray[*]}"
}
myarray=(1 2 3 4 5)
echo "The original array is ${myarray[*]}"
testit ${myarray[*]}
编写test11.sh脚本
#!/bin/bash
function addarray {
local sum=0
local newarray
newarray=($(echo "$@"))
for value in ${newarray[*]}
do
sum=$[ $sum + $value ]
done
echo $sum
}
myarray=(1 2 3 4 5)
echo "The original array is: ${myarray[*]}"
arg1=$(echo ${myarray[*]})
result=$(addarray $arg1)
echo "The result is $result"
17.4.2 从函数返回数组
从函数里向shell脚本传回数组变量
编写test12.sh脚本
#!/bin/bash
function arraydb1r {
local origarray
local newarray
local elements
local i
origarray=($(echo "$@"))
newarray=($(echo "$@"))
elements=$[ $# -1 ]
for (( i = 0; i<= $elements; i++ ))
{
newarray[$i]=$[ ${origarray[$i]} * 2 ]
}
echo ${newarray[*]}
}
myarray=(1 2 3 4 5)
echo "The original array is: ${myarray[*]}"
arg1=$(echo ${myarray[*]})
result=($(arraydb1r $arg1))
echo "The new array is: ${result[*]}"
17.5 函数递归
使用递归计算阶乘
编写test13.sh脚本
#!/bin/bash
function factorial {
if [ $1 -eq 1 ]
then
echo 1
else
local temp=$[ $1 -1 ]
local result=$(factorial $temp)
echo $[ $result * $1 ]
fi
}
read -p "Enter value: " value
result=$(factorial $value)
echo "The factorial of $value is: $result"
17.6 创建库
如果多个脚本需要使用同一段代码,可以使用函数库文件,然后在多个脚本中引用该库文件
1.创建一个库文件
编写myfuncs文件
function addem {
echo $[ $1 + $2 ]
}
function multem {
echo $[ $1 * $2 ]
}
function divem {
if [ $2 -ne 0 ]
then
echo $[ $1 / $2 ]
else
echo -1
fi
}
2.使用这个库文件
编写test14.sh脚本
#!/bin/bash
. ./myfuncs
value1=10
value2=5
result1=$(addem $value1 $value2)
result2=$(multem $value1 $value2)
result3=$(divem $value1 $value2)
echo "The result of adding them is: $result1"
echo "The result of multiplying them is: $result2"
echo "The result of dividing them is: $result3"
17.7 在命令行上使用函数
17.7.1 在命令行上创建函数
因为shell会解释用户输入的命令,所有可以在命令行上直接定义一个函数
执行一下命令
function divem { echo $[ $1 / $2 ]; }
divem 100 5
警告:在命令行上创建函数时要特别小心。如果给函数起了个跟内建命令或另一个命令相同的名字,函数将会覆盖原来的命令。
17.7.2 在.bashrc文件中定义函数
1.直接定义函数
可以直接在主目录下的.bashrc文件中定义函数
如在文件末尾加上
function addem {
echo $[ $1 + $2 ]
}
2.读取函数文件
可以使用source命令(即点操作符)将库文件中的函数添加到.bashrc脚本中
如在文件末尾加上
. /home/zc/libraries/myfuncs
17.8 实例
函数的应用绝不仅限于创建自己的函数自娱自乐。在开源世界中,共享代码才是关键,而这一点同样适用于脚本函数。这里将说明如何下载、安装、使用GNU shtool shell脚本函数库。
17.8.1 下载及安装
下载地址:ftp://ftp.gnu.org/gnu/shtool/shtool-2.0.8.tar.gz
解压文件:tar -zxvf shtool-2.0.8.tar.gz
17.8.2 构建库
shtool文件必须针对特定的Linux环境进行配置
配置工作必须使用标准的configure和make命令,这两个命令通常用于C编程环境
执行命令
./configure
make
sudo make install
17.8.3 shtool函数库
shtool库提供了大量方便的、可用于shell脚本的函数
shtool库函数
函数:描述
Arx:创建归档文件(包含一些扩展功能)
Echo:显示字符串,并提供了一些扩展构件
fixperm:改变目录树中的文件权限
install:安装脚本或文件
mdate:显示文件或目录的修改时间
mkdir:创建一个或更多目录
Mkln:使用相对路径创建链接
mkshadow:创建一颗阴影树
move:带有替换功能的文件移动
Path:处理程序路径
platform:显示平台标识
Prop:显示一个带有动画效果的进度条
rotate:转置日志文件
Scpp:共享的C预处理器
Slo:根据库的类别,分离链接器选项
Subst:使用sed的替换操作
Table:以表格的形式显示由字段分割(field-separated)的数据
tarball:从文件和目录中创建tar文件
version:创建版本信息文件
shtool函数的使用格式
shtool [options] [function [options] [args]]
17.8.4 使用库
可以在命令行或自己的shell脚本中直接使用shtool函数
编写test16.sh脚本
#!/bin/bash
shtool platform
17.9 小结
shell脚本函数允许将脚本中多处用到的代码放到一个地方。可以创建一个包含该代码块的函数,然后在脚本中通过函数名来引用这块代码,而不用一次次重复写那段代码。