理解和编写 Shell 脚本中的函数 - 第 VI 部分
函数在任何编程语言中都发挥着重要作用。与许多真实的编程语言一样,bash 的函数的实现有限。
什么是函数?
在编程中,函数是执行特定任务的程序的命名部分。从这个意义上说,函数是一种过程或例程。当调用函数时,程序离开当前代码段并开始执行函数内的第一行。每当存在重复代码或任务重复时,请考虑使用函数。
例如,考虑这样的情况:我们需要在特定程序的多个阶段查找数字的阶乘。我们不必每次都编写整个代码(用于计算阶乘),而是可以在块内编写一次计算阶乘的代码部分,并在多个场合重复使用相同的代码。
我们为什么要写函数?
- 它可以帮助我们重用代码。
- 提高程序的可读性。
- 有效使用程序内的变量。
- 允许我们逐部分测试程序。
- 将程序显示为一堆子步骤。
shell脚本中的函数
shell脚本中编写函数的一般语法包括以下几种方式。
function func_name {
. . .
commands
. . .
}
or
func_name ( ) {
. . .
commands
. . .
}
Opening curly braces can also be used in the second line as well.
func_name ( )
{
. . .
commands
. . .
}
您始终可以像我们通常在 shell 脚本中一样在这些功能块中编写有效的命令。现在让我们尝试编写一个简单的脚本,其中包含一个小函数。
#!/bin/bash
call_echo ( ) {
echo ‘This is inside function’
}
op=$1
if [ $# -ne 1 ]; then
echo "Usage: $0 <1/0>"
else
if [ $1 = 0 ] ; then
echo ‘This is outside function’
elif [ $1 = 1 ] ; then
call_echo
else
echo ‘Invalid argument’
fi
fi
exit 0
函数定义必须在第一次调用之前。没有什么比在调用函数之前“声明函数”更好的了。我们总是可以将函数嵌套在函数中。
注意:- 编写空函数总是会导致语法错误。
当同一函数被多次定义时,最终版本就是被调用的版本。让我们举个例子。
#!/bin/bash
func_same ( ) {
echo ‘First definition’
}
func_same ( ) {
echo ‘Second definition’
}
func_same
exit 0
函数接受参数并返回值
让我们更深入地考虑采用参数和返回值的函数。为了从函数返回一个值,我们使用内置的“return”shell。语法如下。
func_name ( ) {
. . .
commands
. . .
return $ret_val
}
类似地,我们可以将参数传递给用空格分隔的函数,如下所示。
func_name $arg_1 $arg_2 $arg_3
在函数内部,我们可以按 $1、$2、$3 等顺序访问参数。查看以下示例脚本,使用函数查找两个整数的最大值,以增加清晰度。
#!/bin/bash
USG_ERR=7
max_two ( ) {
if [ "$1" -eq "$2" ] ; then
echo 'Equal'
exit 0
elif [ "$1" -gt "$2" ] ; then
echo $1
else
echo $2
fi
}
err_str ( ) {
echo "Usage: $0 <number1> <number2>"
exit $USG_ERR
}
NUM_1=$1
NUM_2=$2
x
if [ $# -ne 2 ] ; then
err_str
elif [ `expr $NUM_1 : '[0-9]*'` -eq ${#NUM_1} ] ; then
if [ `expr $NUM_2 : '[0-9]*'` -eq ${#NUM_2} ] ; then
max_two $NUM_1 $NUM_2
else
err_str
fi
else
err_str
fi
exit 0
上面的代码看起来有点复杂,但是我们仔细看一下就很简单了。首先嵌套 if-else if 行用于验证目的,即借助正则表达式检查参数的数量和类型。之后,我们使用两个命令行参数调用该函数并在其中显示结果本身。这是因为我们无法从函数返回大整数。解决此问题的另一种方法是使用全局变量将结果存储在函数内。下面的脚本解释了这种方法。
#!/bin/bash
USG_ERR=7
ret_val=
max_two ( ) {
if [ "$1" -eq "$2" ] ; then
echo 'Equal'
exit 0
elif [ "$1" -gt "$2" ] ; then
ret_val=$1
else
ret_val=$2
fi
}
err_str ( ) {
echo "Usage: $0 <number1> <number2>"
exit $USG_ERR
}
NUM_1=$1
NUM_2=$2
if [ $# -ne 2 ] ; then
err_str
elif [ `expr $NUM_1 : '[0-9]*'` -eq ${#NUM_1} ] ; then
if [ `expr $NUM_2 : '[0-9]*'` -eq ${#NUM_2} ] ; then
max_two $NUM_1 $NUM_2
echo $ret_val
else
err_str
fi
else
err_str
fi
exit 0
现在尝试一些令人兴奋的问题,这些问题在之前的 shell 脚本系列中使用函数进行了解释,如下所示。
- 了解基本的 Linux Shell 脚本语言技巧 – 第一部分
- 供 Linux 新手学习 Shell 编程的 5 个 Shell 脚本 - 第二部分
- 畅游 Linux BASH 脚本世界 – 第三部分
- Linux Shell 编程的数学方面 – 第四部分
- 使用 Shell 脚本语言计算数学表达式 - 第五部分
在下一部分中,我将更深入地了解功能特性,例如使用局部变量、递归等。随时关注评论。