在小节中,我们将介绍bash函数的基础知识以及它们在bash shell脚本中的工作方式。
bash脚本中的函数是重用代码的绝佳选择。Bash函数可以定义为一组命令,在bash脚本中多次调用。bash函数使脚本更具可读性,并避免一次又一次地编写相同的代码。它还允许开发人员将复杂而冗长的代码分解为小部分,可以在需要时调用它们。可以随时重复调用函数,这样就能够重用,优化和最小化代码。
以下是有关bash函数的一些要点:
- 在shell脚本中必须先声明函数,然后才能使用它。
- 参数可以传递给函数,并在函数内部以
$1
,$2
,$n
等访问。 - 在函数内分配局部变量,此变量的范围仅是该特定函数。
- Bash shell中使用函数可以覆盖内置命令。
1. 语法
bash声明函数的语法有两种格式定义:
第一种方法:以函数名称开头,后跟括号。这是最优选且最常用的方法,语法如下:
function_name () {
commands
}
单行语法如下:
function_name () { commands; }
第二种方法:以函数保留字开头,后跟函数名称:
function function_name {
commands
}
单行语法如下:
function_name () { commands; }
与大多数编程语言相比,Bash函数有所限制。下面通过一些示例来理解这个概念。
示例:方法1
#!/bin/bash
welcome () {
echo 'Welcome to Yiibai.'
}
welcome
执行上面示例代码,得到以下结果:
Welcome to Yiibai.
示例:方法2
#!/bin/bash
function welcome () {
echo 'Welcome to Yiibai.'
}
welcome
执行上面示例代码,得到以下结果:
Welcome to Yiibai.
2. 传递参数
像大多数编程语言一样,还可以传递参数并在bash函数中处理数据。我们可以将数据插入函数中,就像将命令行参数传递给bash脚本一样。
要将参数传递给bash函数,需要在函数名称之后插入它们。在函数名称和参数之间使用空格,在参数周围使用双引号以防止参数中带有空格的参数解析错误也是一个不错的选择。
以下是有关将参数传递给bash函数的一些要点:
- 给定的参数以
$1
,$2
,$3
,...$n
的形式访问,对应于函数名后参数的位置。 $0
变量的值是函数的名称。$#
变量用于保存赋予函数的位置自变量/参数的数量。$*
和$@
变量用于保存赋予函数的所有参数。- 当
$*
与双引号(即"$*"
)一起使用时,它将扩展为一个由空格分隔的字符串。例如,"$1 $2 $n"
等。 - 当
$@
与双引号(即"$@"
)一起使用时,它将扩展为单独的字符串。例如,"$1" "$2" "$n"
等。 - 当
$*
和$#
不与双引号一起使用时,它们都是相同的。
- 当
以下是说明如何将参数传递给函数以及如何访问函数内部参数的过程的代码。
Bash脚本
#!/bin/bash
#Script to pass and access arguments
function_arguments(){
echo $1
echo $2
echo $3
echo $4
echo $5
}
#Calling function_arguments
function_arguments "We" "welcome" "you" "on" "Yiibai"
执行上面示例代码,得到以下结果:
在此脚本中,在调用function_arguments
函数之后添加了值:"We"
"welcome"
"you"
"on"
"Yiibai"
。这些值将作为参数传递到function_arguments
并存储在局部变量中。但是,与其他语言不同,解释器将传递的值存储到预定义的变量中,然后根据传递的参数顺序进行命名。
例如,
"We"
存储在变量$1
中。"welcome"
存储在变量$3
中。"you"
存储在变量$3
中。"on"
存储到变量$4
中。"Yiibai"
存储在变量$5
中。
3. 变量的作用域
全局变量定义为可以在脚本内的任意位置访问的变量,而不管它的范围如何。默认情况下,所有变量都定义为全局变量,即使它们在函数内部声明也是如此。还可以将变量创建为局部变量。可以使用local
关键字在函数体内声明局部变量。首次分配关键字时。它们只能在该函数内部访问。可以在不同的函数中创建具有相同名称的局部变量。要添加局部变量,使用以下语法:
local var_name=<var_value>
为了更好地理解变量作用域如何在Bash脚本中工作,请查看以下示例:
Bash脚本
#!/bin/bash
v1='A'
v2='B'
my_var () {
local v1='C'
v2='D'
echo "Inside Function"
echo "v1 is $v1."
echo "v2 is $v2."
}
echo "Before Executing the Function"
echo "v1 is $v1."
echo "v2 is $v2."
my_var
echo "After Executing the Function"
echo "v1 is $v1."
echo "v2 is $v2."
执行上面示例代码,得到以下结果:
在上面输出中,如果在函数体内设置与全局变量同名的局部变量,则它将优先于全局变量(即,局部变量覆盖全局变量)。可以在函数内修改全局变量。
4. 返回值
大多数编程语言都具有函数返回值的概念。函数可以将数据发送回原始调用位置。与“真实”编程语言中的函数不同,Bash函数不提供在调用时返回值的支持。但是,它们允许设置返回状态,这种状态类似于程序或命令如何以退出状态退出。bash函数完成时,其返回值是函数中最后执行的语句的状态。对于成功状态,它将返回0
,对于失败,将返回1-255
范围内的非零十进制数。
可以使用关键字return
指示返回状态,并将它分配给变量$?
。return
语句终止函数并用作函数的退出状态。
例如,参考以下代码:
#!/bin/bash
#Setting up a return status for a function
print_it () {
echo Hello $1
return 5
}
print_it User
print_it Reader
echo The previous function returned a value of $?
执行上面示例代码,得到以下结果:
从函数返回值的另一个更好的选择是使用echo
或printf
命令将打印值发送到stdout
,如下脚本代码所示:
#!/bin/bash
print_it () {
local my_greet="Welcome to Yiibai."
echo "$my_greet"
}
my_greet="$(print_it)"
echo $my_greet
5. 覆盖命令
可以通过创建与要覆盖的命令同名的函数来覆盖bash命令。例如,如果想覆盖echo
命令,那么只需要创建一个名称为echo
的函数即可。
覆盖bash命令的概念在某些情况下可能会很有用,例如当要使用带有特定选项的命令时,或者当我们不喜欢在脚本中多次为整个命令提供选项时。在这种情况下,可以将内置bash命令覆盖为带选项的命令。下面通过一些示例来了解在Bash Shell脚本中覆盖命令:
示例
在此示例中,我们将覆盖echo
命令,并将时间戳以参数的形式添加到了echo
命令中。
Bash脚本
#!/bin/bash
#Script to override command using function
echo () {
builtin echo -n `date +"[%m-%d %H:%M:%S]"` ": "
builtin echo $1
}
echo "Welcome to Yiibai."
总结
在本小节中,我们演示了有关Bash函数的使用和技巧。Bash函数是一个开发用于执行特定操作的可重用代码块。定义后可以在脚本中多次调用它。