有两种格式可以用来在 bash shell
脚本中创建函数。
第一种格式采用关键字 function
,后跟分配给该代码块的函数名。
function name {
commands
}
第二种格式更接近于其他编程语言中定义函数的方式。
name() {
commands
}
name
:定义了赋予函数的唯一名称。脚本中定义的每个函数都必须有一个唯一的名称。commands
:构成函数的一条或多条 bash shell
命令。在调用该函数时,bash shell
会按命令在 函数中出现的顺序依次执行,就像在普通脚本中一样。要在脚本中使用函数,只需要像其他 shell
命令一样,在行中指定函数名就行了。
测试示例:
onlylove@ubuntu:~/my/shell/01$ ls
test.sh
onlylove@ubuntu:~/my/shell/01$ cat test.sh
#!/bin/bash
function f1 {
echo "hello world f1"
}
f2(){
echo "hello world f2"
}
f1
f2onlylove@ubuntu:~/my/shell/01$
onlylove@ubuntu:~/my/shell/01$ ./test.sh
hello world f1
hello world f2
onlylove@ubuntu:~/my/shell/01$
默认情况下,函数的退出状态码是函数中最后一条命令返回的退出状态码。在函数执行结束 后,可以用标准变量 $?
来确定函数的退出状态码。
bash shell
使用 return
命令来退出函数并返回特定的退出状态码。return
命令允许指定一个 整数值来定义函数的退出状态码,从而提供了一种简单的途径来编程设定函数退出状态码。
特别说明:
0~255
。$?
变量提取函数返回值之前执行了其他命令,函数的返回值就会丢失。1、shell
脚本内容
#!/bin/bash
function f1 {
echo "hello world f1"
}
f2(){
echo "hello world f2"
}
f1
echo "f1 The exit status is: $?"
f2
echo "f2 The exit status is: $?"
2、测试
onlylove@ubuntu:~/my/shell/01$ ls
test.sh
onlylove@ubuntu:~/my/shell/01$ ./test.sh
hello world f1
f1 The exit status is: 0
hello world f2
f2 The exit status is: 0
onlylove@ubuntu:~/my/shell/01$
将函数输出保存在变量中:
result=$(dbl)
这个命令会将dbl函数的输出赋给$result变量。
1、shell
脚本内容
#!/bin/bash
function f1 {
echo "hello world f1"
return 5
}
f2(){
echo "hello world f2"
return 8
}
result1=$(f1)
echo "f1 The exit status is: $?"
echo "f1 The exit status is: ${result1}"
result2=$(f2)
echo "f2 The exit status is: $?"
echo "f1 The exit status is: ${result2}"
2、测试
onlylove@ubuntu:~/my/shell/01$ ls
test.sh
onlylove@ubuntu:~/my/shell/01$ ./test.sh
f1 The exit status is: 5
f1 The exit status is: hello world f1
f2 The exit status is: 8
f1 The exit status is: hello world f2
onlylove@ubuntu:~/my/shell/01$
函数可以使用标准的参数环境变量来表示命令行上传给函数的参数。例如,函数名会在 $0
变量中定义,函数命令行上的任何参数都会通过 $1
、$2
等定义。
给 shell
脚本程序员带来麻烦的原因之一就是变量的作用域。作用域是变量可见的区域。函数 中定义的变量与普通变量的作用域不同。也就是说,对脚本的其他部分而言,它们是隐藏的。
1、全局变量
全局变量是在 shell
脚本中任何地方都有效的变量。如果你在脚本的主体部分定义了一个全局变量,那么可以在函数内读取它的值。类似地,如果你在函数内定义了一个全局变量,可以在脚本的主体部分读取它的值。
2、局部变量
local
关键字保证了变量只局限在该函数中。如果脚本中在该函数之外有同样名字的变量, 那么 shell
将会保持这两个变量的值是分离的。现在你就能很轻松地将函数变量和脚本变量隔离开 了,只共享需要共享的变量。
1、脚本内容
#!/bin/bash
a=100
function f {
local a=500
echo "\$0 = $0"
echo "\$1 = $1"
echo "\$2 = $2"
echo "f a = $a"
return 0
}
echo "main a = $a"
f 1 2
2、测试
onlylove@ubuntu:~/my/shell/01$ ls
test.sh
onlylove@ubuntu:~/my/shell/01$ ./test.sh
main a = 100
$0 = ./test.sh
$1 = 1
$2 = 2
f a = 500
onlylove@ubuntu:~/my/shell/01$
1、shell
脚本编程
#!/bin/bash
function f {
echo "The parameters are: $@"
thisarray=$1
echo "The received array is ${thisarray[*]}"
}
myarray=(1 2 3 4 5)
echo "The original array is: ${myarray[*]}"
f $myarray
2、测试
onlylove@ubuntu:~/my/shell/01$ ls
test.sh
onlylove@ubuntu:~/my/shell/01$ ./test.sh
The original array is: 1 2 3 4 5
The parameters are: 1
The received array is 1
onlylove@ubuntu:~/my/shell/01$
特别说明:将数组变量作为函数参数,函数只会取数组变量的第一个值。
要解决这个问题,你必须将该数组变量的值分解成单个的值,然后将这些值作为函数参数使用。在函数内部,可以将所有的参数重新组合成一个新的变量。
1、shell
脚本内容
#!/bin/bash
# 直接将数组作为参数传入
# function f {
# echo "The parameters are: $@"
# thisarray=$1
# echo "The received array is ${thisarray[*]}"
# }
#
# myarray=(1 2 3 4 5)
# echo "The original array is: ${myarray[*]}"
# f $myarray
function f {
local newarray
newarray=($@)
echo "The new array value is: ${newarray[*]}"
}
myarray=(1 2 3 4 5)
echo "The original array is: ${myarray[*]}"
f ${myarray[*]}
2、测试
onlylove@ubuntu:~/my/shell/01$ ./test.sh
The original array is: 1 2 3 4 5
The new array value is: 1 2 3 4 5
onlylove@ubuntu:~/my/shell/01$
在函数内部将所有数据展开,从函数外部将数据进行重组。
1、shell
脚本内容
#!/bin/bash
function f {
local newarray=(6 7 8 9 0)
echo ${newarray[*]}
}
# 初始化变量
myarray=(1 2 3 4 5)
echo "The original array is: ${myarray[*]}"
# 调用函数
# 将函数返回值保存在 myarray 数组中(重新组装值)
myarray=$(f)
echo "The myarray array is: ${myarray[*]}"
myarray1=$(f)
echo "The myarray1 array is: ${myarray1[*]}"
2、测试
onlylove@ubuntu:~/my/shell/01$ ls
test.sh
onlylove@ubuntu:~/my/shell/01$ ./test.sh
The original array is: 1 2 3 4 5
The myarray array is: 6 7 8 9 0 2 3 4 5 # 特别注意这行
The myarray1 array is: 6 7 8 9 0
onlylove@ubuntu:~/my/shell/01$
以上测试过程中,对函数调用使用 $(f)
方式。( ) 括号表示开启一个子 shell
执行括号中命令。
1、shell
脚本内容
#!/bin/bash
function f {
local newarray=(6 7 8 9 0)
echo " The function f "
echo ${newarray[*]}
}
# 初始化变量
myarray=(1 2 3 4 5)
echo "The original array is: ${myarray[*]}"
# 调用函数
# 将函数返回值保存在 myarray 数组中(重新组装值)
myarray=$(f)
echo "The myarray array is: ${myarray[*]}"
myarray1=$(f)
echo "The myarray1 array is: ${myarray1[*]}"
2、测试
onlylove@ubuntu:~/my/shell/01$ ls
test.sh
onlylove@ubuntu:~/my/shell/01$ ./test.sh
The original array is: 1 2 3 4 5
The myarray array is: The function f
6 7 8 9 0 2 3 4 5
The myarray1 array is: The function f
6 7 8 9 0
onlylove@ubuntu:~/my/shell/01$
分析:“The myarray array is: ${myarray[*]}
” 语句中插入 "The function f
"语句,也就是说明 f
函数和主 shell
同时执行。