理解和编写 Shell 脚本中的函数 - 第六部分
函数在任何编程语言中都扮演着重要的角色。与许多实际编程语言一样,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
接受参数并返回值的函数
让我们更深入地考虑一下接受参数并返回值的函数。要从函数返回值,我们使用 shell 内置的“return”。语法如下。
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 脚本语言技巧 - 第一部分
- 5 个 Linux 新手学习 Shell 编程的 Shell 脚本 - 第二部分
- 探索 Linux BASH 脚本世界 – 第三部分
- Linux Shell 编程的数学方面 - 第四部分
- 在 Shell 脚本语言中计算数学表达式 - 第五部分
我将在下一部分中对使用局部变量、递归等功能特性进行更深入的介绍。请继续关注评论。