Appearance
创建函数
基本的脚本函数
创建函数
有两种格式
bash
function name {
commands
}
注意空格
bash
name() {
commands
}
使用函数
要使用函数直接指定函数名就可以了
bash
1 #!/bin/bash
2
3 function func1 {
4 echo "This is an example of an function"
5 }
6 count=1
7 while [ $count -le 5 ]
8 do
9 func1
10 count=$[ $count+1 ]
11 done
12
13 echo "This is the end of the loop"
14 func1
15 echo "This is the end of the scrip"
jiao@jiao-virtual-machine:~/桌面/linux-shell/17$ test1.sh
This is an example of an function
This is an example of an function
This is an example of an function
This is an example of an function
This is an example of an function
This is the end of the loop
This is an example of an function
This is the end of the scrip
函数名必须是唯一的,否则也会有问题。如果你重定义了函数,新定义会覆盖原来函数的定义,这一切不会产生任何错误消息
返回值
bash shell 会把函数当成一个小的脚本, 运行结束返回退出状态码
默认退出状态码
默认情况下,函数的退出状态码是函数中最后一条命令返回的退出状态码。在函数执行结束后,可以用标准变量$?来确定函数的退出状态码
函数中的其他命令出现错误没有体现
使用return命令
l使用return命令来退出函数并返回特定的退出状态码
- 函数一结束就取返回值;
- 退出状态码必须是0~255
使用函数输出
把要输出的值放在变量中
bash
result='dbl'
新函数会用echo语句来显示计算的结果。该脚本会获取dbl函数的输出,而不是查看退出状态码
bash shell脚本非常聪明,并不将其作为STDOUT输出的一部分,并且忽略掉它。如果你用echo语句生成这条消息来向用户查询,那么它会与输出值一起被读进shell变量中
可以通过这种方法返回各种值
bash
1 #!/bin/bash
2
3 function db1 {
4 read -p "Enter a value: " value
5 echo "value is $[ value * 2 ]"
6 }
7 result=$(db1)
8 echo "The new $result"
jiao@jiao-virtual-machine:~/桌面/linux-shell/17$ test4.sh
Enter a value: 34
The new value is 68
在函数中使用变量
向函数传递参数
可以吧函数当做小型的脚本, 可以直接传递参数
bash
func1 $value1 10
bash
1 #!/bin/bash
2
3 function addem {
4 if [ $# -eq 0 ] || [ $# -gt 2 ]
5 then
6 echo -1
7 elif [ $# -eq 1 ]
8 then
9 echo $[ $1+$1 ]
10 else
11 echo $[ $1 + $2 ]
12 fi
13
14 }
15
16 echo -n "Add 10 and 15: "
17 value=$(addem 10 15)
18 echo $value
19 echo -n "Let's try adding just one number: "
20 value=$(addem 10)
21 echo $value
22 echo -n "Now trying adding no numbers: "
23 value=$(addem)
24 echo $value
25 echo -n "Finally, try adding three numbers: "
26 value=$(addem 10 15 20)
27 echo $value
jiao@jiao-virtual-machine:~/桌面/linux-shell/17$ test5.sh
Add 10 and 15: 25
Let's try adding just one number: 20
Now trying adding no numbers: -1
Finally, try adding three numbers: -1
由于函数使用特殊参数环境变量作为自己的参数值,因此它无法直接获取脚本在命令行中的参数值, 它们和脚本主体中的$1和$2变量并不相同。
在函数中处理变量
函数使用两种类型的变量:
- 全局变量
- 局部变量
全局变量
默认情况下, 在脚本中定义的变量都是全局变量, 函数外定义的变量都可以在函数中正常访问
bash
1 #!/bin/bash
2
3 function db1 {
4 value=$[ $value*2 ]
5 }
6 read -p "Enter a value: " value
7 db1
8 echo "The new value is : $value"
jiao@jiao-virtual-machine:~/桌面/linux-shell/17$ myts.sh test6.sh
Enter a value: 45
The new value is : 90
局部变量
在变量之前加上local, 一般是在函数内使用
数组变量和函数
向函数传递数组变量
- 错误示范
bash
1 #!/bin/bash
2
3 function testit {
4 echo "The parameters are: $@"
5 thisarray=$1
6 echo "The receive array is ${thisarray[*]}"
7
8 }
9 myarray=(1 2 3 4 5)
10 echo "The original array is: ${myarray[*]}"
11 testit $myarray
12 echo $myarray
jiao@jiao-virtual-machine:~/桌面/linux-shell/17$ myts.sh test7.sh
The original array is: 1 2 3 4 5
The parameters are: 1
The receive array is 1
1
传递的只是第一个参数
bash
1 #!/bin/bash
2
3 function testit {
4 local newarray
5 newarray=$( echo "$@" )
6 echo "The new array value is: ${newarray[*]}"
7 }
8 myarray=(1 2 3 4 5)
9 echo "The original array is: ${myarray[*]}"
10 testit ${myarray[*]}
jiao@jiao-virtual-machine:~/桌面/linux-shell/17$ test7.sh
The original array is: 1 2 3 4 5
The new array value is: 1 2 3 4 5
从函数返回数组
函数用echo语句来按正确顺序输出单个数组值,然后脚本再将它们重新放进一个新的数组变量中
bash
1 #!/bin/bash
2
3 function arrayblr {
4 local origarray
5 local newarray
6 local elements
7 local i
8 origarray=($(echo "$@"))
9 newarray=($(echo "$@"))
10 elements=$[ $# -1 ]
11 for ((i=0 ; i<=elements; i++))
12 {
13 newarray[$i]=$[ ${origarray[$i]} * 2 ]
14 }
15 echo ${newarray[*]}
16 }
17 myarray=(1 2 3 4 5)
18 echo "The original array is: ${myarray[*]}"
19 arg1=$(echo ${myarray[*]})
20 result=($(arrayblr $arg1))
21 echo "The new array is: ${result[*]}"
jiao@jiao-virtual-machine:~/桌面/linux-shell/17$ test8.sh
The original array is: 1 2 3 4 5
The new array is: 2 4 6 8 10
函数递归
bash
1 #!/bin/bash
2 function factorial {
3 if [ $1 -eq 1 ]
4 then
5 echo 1
6 else
7 local temp=$[ $1-1 ]
8 local result=` factorial $temp `
9 echo $[ $result * $1 ]
10 fi
11 }
12
13 read -p "Enter your value: " value
14 result=$(factorial $value )
15 echo $result
创建库
source命令会在当前shell上下文中执行命令,而不是创建一个新shell。可以用source命令来在shell脚本中运行库文件脚本。
source命令有个快捷的别名,称作点操作符(dot operator)。要在shell脚本中运行myfuncs库文件,只需添加下面这行:
bash
. ./myfuncs
bash
1 #/bin/bash
2 . ./myfunc
3 value1=10
4 value2=5
5 result1=$(addem $value1 $value2)
6 result2=$(multem $value1 $value2)
7 result3=$(diven $value1 $value2)
8 echo $result1
9 echo $result2
10 echo $result3
jiao@jiao-virtual-machine:~/桌面/linux-shell/17$ test11.sh
15
50
2
在命令行上使用函数
因为一旦在shell中定义了函数,你就可以在整个系统中使用它了,无需担心脚本是不是在PATH环境变量里。重点在于让shell能够识别这些函数。有几种方法可以实现
在命令行上创建函数
因为shell会解释用户输入的命令,所以可以在命令行上直接定义一个函数。有两种方法。一种方法是采用单行方式定义函数
bash
jiao@jiao-virtual-machine:~/桌面/linux-shell/17$ function divem { echo $[ $1 / $2 ]; }
jiao@jiao-virtual-machine:~/桌面/linux-shell/17$ divem 8 4
2
当在命令行上定义函数时,你必须记得在每个命令后面加个分号,这样shell就能知道在哪里是命令的起止了。
另一种方法是采用多行方式来定义函数。在定义时,bash shell会使用次提示符来提示输入更多命令。用这种方法,你不用在每条命令的末尾放一个分号,只要按下回车键就行
bash
jiao@jiao-virtual-machine:~/桌面/linux-shell/17$ function multem {
> echo $[ $1 * $2 ]
> }
jiao@jiao-virtual-machine:~/桌面/linux-shell/17$ multem 5 4
20
在命令行上创建函数时要特别小心。如果你给函数起了个跟内建命令或另一个命令相同的名字,函数将会覆盖原来的命令
在.bashrc文件中定义函数
- 直接定义函数
- 读取函数文件
更好的是,shell还会将定义好的函数传给子shell进程,这样一来,这些函数就自动能够用于该shell会话中的任何shell脚本了
实例
你可以下载大量各式各样的函数,并将其用于自己的应用程序中
使用GNU shtool库下载并安装到你的系统中
bash
wget ftp://ftp.gnu.org/gnu/shtool/shtool-2.0.8.tar.gz
tar -zxvf shtool-2.0.8.tar.gz
库函数
函数 | 描述 |
---|---|
Arx | 创建归档文件(包含一些扩展功能) |
Echo | 显示字符串,并提供了一些扩展构件 |
fixperm | 改变目录树中的文件权限 |
install | 安装脚本或文件 |
mdate | 显示文件或目录的修改时间 |
mkdir | 创建一个或更多目录 |
Mkln | 使用相对路径创建链接 |
mkshadow | 创建一棵阴影树 |
move | 带有替换功能的文件移动 |
Path | 处理程序路径 |
platform | 显示平台标识 |
Prop | 显示一个带有动画效果的进度条 |
rotate | 转置日志文件 |
Scpp | 共享的C预处理器 |
Slo | 根据库的类别,分离链接器选项 |
Subst | 使用sed的替换操作 |
Table | 以表格的形式显示由字段分隔(field-separated)的数据 |
tarball | 从文件和目录中创建tar文件 |
version | 创建版本信息文件 |
bash
jiao@jiao-virtual-machine:~/shtool-2.0.8$ test12.sh | shtool prop -p "Waiting..."
Waiting...
会显示一个简单的动画, 并且不输出原来的内容, 输出定义的内容
能看到多少进度条取决于CPU能以多快的速度列出/usr/bin中的文件!-p选项允许你定制输出文本,这段文本会出现在进度条字符之前
bash
jiao@jiao-virtual-machine:~/shtool-2.0.8$ shtool platform
Ubuntu 21.10 (AMD64)