为了实现模块化设计和代码重用,很多编程语言支持函数或过程,Linux shell也支持函数定义和调用。
Linux shell中的函数与其它编程语言很多有相似之处,也有自己独特之处。
1 函数的定义
1.1 标准格式
function 函数名()
{
语句或命令1
……
语句或命令n
[return 返回值]
}
其中:
- function是 Shell 中的关键字,专门用来定义函数;
- 由{ }包围的部分称为函数体,调用一个函数,实际上就是执行函数体中的代码。
- return 是 Shell 关键字,专门用在函数中返回一个值;如果不用返回值,这一句也可以不写。
这个格式是不是与JavaScript的函数定义格式很像?
1.2 简化格式
在实际实用中,还有两种简化格式:
1.2.1 简化格式1——省略function关键字
我们可以把function关键字省略不写,就有了下面这种简化格式:
函数名()
{
语句或命令1
……
语句或命令n
[return 返回值]
}
1.2.2 简化格式2——省略函数名后面的小括号
如果我们写了 function 关键字,也可以省略函数名后面的小括号,就有了下面这种简化格式:
function 函数名
{
语句或命令1
……
语句或命令n
[return 返回值]
}
1.3 建议
建议使用1.1的标准格式,保持与其它编程语言的书写兼容性。
2 函数的参数
2.1 函数在定义时不能指明参数
尽管Linux Linux Shell中的函数定义格式与JavaScript的函数定义格式很像,但它也在有自己的特别之处,那就是函数在定义时不能指明参数,但是在调用时却可以传递参数,并且给它传递什么参数它就接收什么参数。
2.2 函数体内使用参数信息的方式
函数体内脚本内获取参数的格式为:
${n}
其中n 代表一个数字,0为执行脚本的命令行命令, 1 为执行脚本的第一个参数,2 为执行脚本的第二个参数,依此类推……
- 当n > 10时,可以省略{},简写为$n。
- 当n>=10时,务必使用${n}
除此之外,还有几个特殊的参数处理信息:
参数处理 |
说明 |
$# |
传递到脚本的参数个数 |
$* |
以一个单字符串显示所有向脚本传递的参数。 如"$*"用「"」括起来的情况、以"$1 $2 … $n"的形式输出所有参数。 |
$@ |
与$*相同,但是使用时加引号,并在引号中返回每个参数。 如"$@"用「"」括起来的情况、以"$1" "$2" … "$n" 的形式输出所有参数。 |
$$ |
脚本运行的当前进程ID号 |
$! |
后台运行的最后一个进程的ID号 |
$- |
显示Shell使用的当前选项 |
$? |
显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。 |
3 函数的执行(调用)
格式:
函数名 [参数1 参数2 …… 参数n]
与JavaScript一样,Linux Shell 对函数定义和调用的顺序不做限制,你可以将定义放在调用的前面,也可以反过来,将定义放在调用的后面。
但是,与JavaScript不同的地方:
- 函数名后面不用()。
- 如果要传递参数,那么参数以空格分隔。
4.函数定义和调用实例
我们定义一个函数x:
function x()
{
echo cmd: $0;
echo param number:$#;
echo they are $@;
echo 1-$1;
echo 2-${2};
echo 3-$3;
echo 4-$4;
echo 5-$5;
echo 6-$6;
echo 7-$7;
echo 8-$8;
echo 9-$9;
echo 10-${10};
return 0;
};
在函数体中:
- 我们用echo命令首先显示命令行命令($0)
- 然后显示命令行参数个数($#)
- 接着我们显示所有的命令行参数($@)
- 然后我们逐个显示每个参数
- 最后我们用return语句返一个值0
4.1 bash中
cs @edu bash $ function x() {echo cmd: $0; echo param number:$#; echo they are $@; echo 1-$1; echo 2-${2}; echo 3-$3; echo 4-$4; echo 5-$5; echo 6-$6;echo 7-$7; echo 8-$8; echo 9-$9; echo 10-${10}; return 0;}; x a1 b2 c3 d4 e5 f6 h7 i8 j9 k10; echo exit code: $?
bash: syntax error near unexpected token `{echo'
cs @edu bash $ function x() { echo cmd: $0; echo param number:$#; echo they are $@; echo 1-$1; echo 2-${2}; echo 3-$3; echo 4-$4; echo 5-$5; echo 6-$6;echo 7-$7; echo 8-$8; echo 9-$9; echo 10-${10}; return 0;}; x a1 b2 c3 d4 e5 f6 h7 i8 j9 k10; echo exit code: $?
cmd: bash
param number:10
they are a1 b2 c3 d4 e5 f6 h7 i8 j9 k10
1-a1
2-b2
3-c3
4-d4
5-e5
6-f6
7-h7
8-i8
9-j9
10-k10
exit code: 0
cs @edu bash $
在命令行中,我们先定义了函数x,然后调用函数x并参递了参数10个参数:
x a1 b2 c3 d4 e5 f6 h7 i8 j9 k10
最后我们使用命令
echo exit code: $?
显示函数x的返回值为0
在bash的命令行中,函数体开始的{和后面的命令或语句要用空格分隔。
4.2 zsh中
cs@ edu zsh $ function x() {echo cmd: $0; echo param number:$#; echo they are $@; echo 1-$1; echo 2-${2}; echo 3-$3; echo 4-$4; echo 5-$5; echo 6-$6;echo 7-$7; echo 8-$8; echo 9-$9; echo 10-${10}; return 0;}; x a1 b2 c3 d4 e5 f6 h7 i8 j9 k10; echo exit code: $?
cmd: x
param number:10
they are a1 b2 c3 d4 e5 f6 h7 i8 j9 k10
1-a1
2-b2
3-c3
4-d4
5-e5
6-f6
7-h7
8-i8
9-j9
10-k10
exit code: 0
代码跟在bash中是一样的,但是zsh的命令行中不要求函数体开始的{和后面的命令或语句用空格分隔。
4.3 使用for循环来简化代码
上面的实例中,要逐个输出参数,我们还可以使用for语句来进行简化。
function x()
{
echo cmd: $0;
echo param number:$#;
echo they are $@;
j=1;
for i in $@
do
echo $j-$i;
((j++));
done
return 0;
};
4.3.1 在bash中
cs @ edu bash $ function x(){ echo cmd: $0; echo param number:$#; echo they are $@; j=1; for i in $@; do echo $j-$i; ((j++));done;return 0; };x a1 b2 c3 d4 e5 f6 h7 i8 j9 k10; echo exit code: $?
cmd: bash
param number:10
they are a1 b2 c3 d4 e5 f6 h7 i8 j9 k10
1-a1
2-b2
3-c3
4-d4
5-e5
6-f6
7-h7
8-i8
9-j9
10-k10
exit code: 0
4.3.2 在zsh中
cs @ edu zsh $ function x(){ echo cmd: $0; echo param number:$#; echo they are $@; j=1; for i in $@; do echo $j-$i; ((j++));done;return 0; };x a1 b2 c3 d4 e5 f6 h7 i8 j9 k10; echo exit code: $?
cmd: x
param number:10
they are a1 b2 c3 d4 e5 f6 h7 i8 j9 k10
1-a1
2-b2
3-c3
4-d4
5-e5
6-f6
7-h7
8-i8
9-j9
10-k10
exit code: 0