一、脚本函数基础
函数 是一个脚本代码块。你可以为其命名,并在脚本任何位置重用它。
1.1 创建函数
bash shell中创建函数的语法有两种
function name {
commands
}
name() {
commands
}
1.2 使用函数
要在脚本中使用函数,只需像其他shell命令一样写出 函数名 即可:
#!/usr/bin/bash
function func1 {
echo "this is an example of a function "
}
func1
#在bash中执行脚本
$ ./func.sh
this is an example of a function
二、函数返回值
bash shell把函数视为一个小型脚本,运行时会返回一个退出状态码。
有3种方法能为函数生成退出状态码
2.1 默认的退出状态码
默认情况下,函数的退出状态码是函数最后一个命令返回的状态码。函数结束后,可以使用 $?
来确定函数的退出状态码。
#!/usr/bin/bash
function func1 {
echo "this is an example of a function "
ls -l badfile
}
func1
echo exit status is $?
#在bash中执行脚本
$ ./func.sh
this is an example of a function
ls: cannot access 'badfile': No such file or directory
exit status is 2
该函数的退出状态码是2,因为函数最后一个命令执行失败了。但是无法知道函数其他命令是否执行成功。
#!/usr/bin/bash
function func1 {
ls -l badfile
echo "this is an example of a function "
}
func1
echo exit status is $?
$ ./func.sh
ls: cannot access 'badfile': No such file or directory
this is an example of a function
exit status is 0
虽然函数第一个 ls 命令执行失败了,但是退出状态码为0。
2.2 使用return命令
bash shell 会使用return命令以特定的退出状态码退出函数。return命令允许指定一个整数值。
#!/usr/bin/bash
function dbl {
read -p "Enter a value:" value
echo double the value
return $[ $value *2 ]
}
dbl
echo exit status is $?
$ ./func.sh
Enter a value:100
double the value
exit status is 200
当用这种方法从函数中返回时,一定要小心。为了避免这个问题,牢记两个技巧。
- 函数执行一结束立即读取返回值
- 退出状态码必须介于0~255
2.3 使用函数输出
正如将命令的输出保存到shell变量一样,也可以将函数的输出保存到shell变量中。
result=$(dbl)
例:
#!/usr/bin/bash
function dbl {
read -p "Enter a value:" value
echo double the value
echo $[ $value *2 ]
}
result=$(dbl)
echo new value is $result
$ ./func.sh
Enter a value:2000
new value is double the value 4000
$ ./func.sh
Enter a value:10000
new value is double the value 20000
三、在函数中使用变量
在函数中使用变量时要注意他们的定义方式和处理方式。这是shell脚本中常见的错误来源。
3.1 向函数传递参数
bash shell将函数当作小型脚本对待。这意味着可以像普通脚本一样向函数传递参数
函数名 参数1 参数2…
#!/usr/bin/bash
function dbl {
echo $[ $1 *2 ]
}
result=$(dbl 100)
echo new value is $result
$ ./func.sh
new value is 200
3.2 在函数中处理变量
函数有两种变量:
- 全局变量
- 局部变量
3.2.1 全局变量
全局变量 是在shell脚本任何地方都有效的变量。
如果在脚本主体定义了一个全局变量,那么就可以在函数中读取它的值。类似的,在函数内部定义全局变量,在脚本主体也可以访问它的值。
#!/usr/bin/bash
function dbl {
echo $[ $value *2 ]
}
read -p "Enter a value:" value
result=$(dbl)
echo new value is $result
$ ./func.sh
Enter a value:100
new value is 200
3.2.2 局部变量
在变量前加 local关键字 即定义了一个局部变量。
local temp
四、数组变量和函数
在函数中使用数组有点麻烦,需要做一些特殊处理。
4.1 向函数传递数组
如果试图将数组作为函数参数进行传递,则函数只会提取数组的第一个元素。
#!/usr/bin/bash
function dbl {
echo “$@”
}
arr=(1 2 3 4 5)
dbl $arr
$ ./func.sh
“1”
要解决这个问题,必须先将数组拆分成多个数组元素,然后将这些数组元素当作参数传递。最后函数内部再将数组元素组装成数组。
#!/usr/bin/bash
function show_arr {
local arr=($(echo "$@"))
echo ${arr[*]}
}
arr=(1 2 3 4 5)
show_arr ${arr[*]}
./func.sh
1 2 3 4 5
4.2 从函数返回数组
函数向脚本返回数组也采用相似的方法。函数先用 echo 语句按正确顺序输出数组的各个元素,然后脚本再将数组元素组装成新的数组。
#!/usr/bin/bash
function return_arr {
local arr=(1 2 3 4 5)
echo ${arr[*]}
}
result=( $(return_arr) )
echo ${result[*]}
$ ./func.sh
1 2 3 4 5
五、函数递归
阶乘计算:
#!/usr/bin/bash
function factorial {
if [ $1 -gt 1 ]
then
#echo $[ $1 * $(factorial $1-1) ]
local res=$[ $1 * $(factorial $[ $1-1 ]) ]
echo $res
exit
fi
echo 1
}
echo $(factorial $1)
$ ./loop.sh 5
120
$ ./loop.sh 10
3628800
六、创建库
bash shell允许创建函数库,然后在多个脚本中使用。
#loop.sh
#!/usr/bin/bash
function factorial {
if [ $1 -gt 1 ]
then
#echo $[ $1 * $(factorial $1-1) ]
local res=$[ $1 * $(factorial $[ $1-1 ]) ]
echo $res
exit
fi
echo 1
}
func.sh
#!/usr/bin/bash
. ./loop.sh
echo $(factorial $1)
执行
$ ./func.sh 5
120
$ ./func.sh 10
3628800
七、在命令行中使用函数
7.1 在命令行中创建函数
有两种方式可以在命令行中创建函数。
一种是采用单行方式来定义函数:
$ function add2 { echo $[ $1 + $2 ]; }
$ add2 100 200
300
使用单行方式定义函数时,必须在命令后 加分号(;), 这样shell才能知道命令的起止。
另一种是采用多行方式定义函数
$ function add3 {
> echo $[ $1 + $2 ]
> }
$ add3 100 200
300
使用这种方式无需在命令尾部加分号。输入尾部的花括号后shell就知道已完成函数定义。
7.2 在bashrc中定义函数
在命令行中定义函数有一个缺点,就是shell退出时函数会消失。想要解决这个问题,可以将
函数定义到.bashrc文件中。
7.2.1 直接定义函数
将函数直接定义到 .bashrc 文件中。
7.2.2 源引函数文件
将函数定义到单独的文件里。
再在 .bashrc 中添加一行。
. 文件路径