shell 函数
在C语言中,我们可以给一个经常使用的代码块(使用一对大括号{}包起来的代码)添加一个名字,然后直接通过这个名字去复用(调用)这个代码块。这个名字和代码块也就是C语言的函数,这个名字就叫函数名,这个代码块就是函数体(函数的实现)。
在shell脚本中,我们也可以将一组经常使用的命令与一个名称进行关联,后续可以直接通过这个名称来调用执行。这个名称也就成了shell中的函数,shell函数的定义格式如下所示:
[function] 函数名称() 复合命令块 [重定向]
其中[]里的保留字function和重定向是可选的,而符合命令块通常是使用一对大括号{}包起来的命令列表,因此函数的定义格式可以简化为:
函数名称(){
命令1
命令2
if-else组合命令
while-for循环命令
[函数返回值]
}
调用这个函数时,如果需要传递传参,参数放在函数名后面即可,多个参数之间使用空格隔开。
#!/bin/bash
function my_print {
echo "param num: $#"
i=1
for param in $@
do
echo "param$i : $param"
((i++))
done
return $?
}
my_print hello zhaixue.cc
shell中的一些特殊变量$#表示传递的参数个数,$@表示传递进来的所有参数,$?表示最后一个命令的返回状态,可以作为函数的返回值,返回值是可选的。在脚本里定义好函数my_print,后面就可以直接在脚本里调用,参数放在调用函数名的后面,各个参数之间用空格隔开。
脚本的运行结果如下:
root@pc:/home/demo# ./hello.sh
param num: 2
param1: hello
param2: zhaixue.cc
shell间接变量的两种引用方式
通过上面的学习,我们知道,在参数传递过程中,还有一些位置参数可以使用:无论是给脚本传参数,还是给函数传参数,$0表示运行的命令名称,$1表示第一个参数,$2表示第二个参数…,因此,我们可以把上面的函数使用位置参数来实现。
#!/bin/bash
function my_print {
echo "param num: $#"
for((i=1; i<=$#;i++))
do
eval echo "param$i : ${!i}"
done
return $?
}
my_print hello zhaixue.cc
在shell中,我们可以使用$i使用一个变量,但不支持类似于 $$i 或 ${$i} 这种间接使用变量的形式,因此,我们可以使用变量扩展${!i}的形式,shell在解析这个变量时看到这个感叹号,就知道是个i是个间接变量,会将i变量的值作为新的位置变量的名称,并继续扩展这个新的变量。
目前的shell解释器中,bash是支持这种间接变量的引用方式的,而为了保持与其他shell的兼容性,我们可以采用另外一种间接变量的引用方式:eval \$$a
#!/bin/bash
function my_print {
echo "param num: $#"
for((i=1; i<=$#;i++))
do
eval echo "param$i : \$$i"
done
return $?
}
my_print hello zhaixue.cc
如脚本所示,跟上一个脚本的运行结果是一样的:
root@pc:/home/demo# ./hello.sh
param num: 2
param1 : hello
param2 : zhaixue.cc
我们在shell函数my_print中仅仅是打印了传递过来的参数,并未对参数做任何处理。而实际的shell函数一般都是完成某个特定的功能,需要对传递的参数进行各种处理。