Bash 初学者系列 #1:在 Bash 中使用函数

当您的 bash 脚本变得越来越大时,事情会变得非常混乱!

您可能会发现自己在 bash 脚本的不同部分一次又一次地重写相同的代码片段。

幸运的是,您可以通过在 bash 中使用函数来避免重写代码,这将使您的脚本更有组织性和可读性。

在本教程中,您将学习在 bash shell 脚本中创建函数、返回函数值和传递函数参数。

此外,您将了解变量作用域如何工作以及如何定义递归函数。

在 bash 中创建函数

声明 bash 函数有两种不同的语法。以下语法是创建 bash 函数最常用的方法:

function_name () {
commands
}

第二种不太常用的创建 bash 函数的方法是从保留的工作函数开始,后跟函数名称,如下所示:

function function_name {
commands
}

在使用函数时,您应该清楚以下几点:

  • 除非您调用函数,否则函数永远不会运行/执行。
  • 函数定义必须先于对该函数的任何调用。

任何时候你想要一个函数运行,你只需要调用它!函数调用是通过简单地引用函数名来完成的。

看看下面的linuxmi.sh bash 脚本:

#!/bin/bash

hello () {
echo "Hello World! Linux迷 www.linuxmi.com"
}

hello
hello
hello

我定义了一个名为 hello 的函数,它只是将“Hello World”行回显到终端。请注意,我执行了三个 hello 函数调用,因此如果您运行该脚本,您将看到屏幕上打印了三次“Hello World”行:

在 bash 中返回函数值

在许多编程语言中,函数在调用时确实会返回一个值;但是,bash 不是这种情况,因为 bash 函数不返回值。

当 bash 函数完成执行时,它返回在 $? 多变的。零表示执行成功或非零正整数 (1-255) 表示失败。

您可以使用 return 语句来更改函数的退出状态。例如,查看以下 linuxmi.sh 脚本:

#! /bin/bash
//Linux迷 www.linuxmi.com
error () {
blabla
return 0
}

error
echo "错误函数的返回状态为: $?"

如果运行 linuxmi.sh bash 脚本,您可能会对输出感到惊讶:

如果没有return 0语句,error函数将永远不会返回非零退出状态,因为 blabla 会导致 未找到命令 错误。

正如您所看到的,即使 bash 函数不返回值,我还是通过改变函数退出状态来解决这个问题。

您还应该知道 return 语句会立即终止函数。

将参数传递给 bash 函数

您可以将参数传递给函数,就像您可以将参数传递给 bash 脚本一样。您只需在执行函数调用时包含参数。

为了演示,让我们看一下以下www.linuxmi.com.sh bash 脚本:

#!/bin/bash
#Linux迷 www.linuxmi.com
iseven () {
if [ $(($1 % 2)) -eq 0 ]; then
echo "$1 是偶数。"
else
echo "$1 是奇数。"
fi
}

iseven 5
iseven 2
iseven 28
iseven 199

iseven() 函数测试数字是偶数还是奇数。我对 iseven() 进行了四次函数调用。对于每个函数调用,我提供了一个数字,它是对 iseven() 函数的第一个扩充,并由函数定义中的 $1 变量引用。

让我们运行 www.linuxmi.com.sh bash 脚本以确保其正常工作:

您还应该清楚 bash 函数参数和bash 脚本参数是两个不同的东西。为了对比差异,请查看以下 linuxmi.sh bash 脚本:

#!/bin/bash
#Linux迷 www.linuxmi.com
fun () {
echo "$1 是 fun() 第一个参数。"
echo "$2 是 fun() 第二个参数。"
}

echo "$1 是脚本的第一个参数。"
echo "$2 是脚本的第二个参数。"

fun linuxmi 93139

使用几个参数运行脚本并观察结果:

如您所见,即使您使用相同的变量 $1 和 $2 来引用脚本参数和函数参数,当从函数内调用时它们会产生不同的结果。

bash 函数中的局部变量和全局变量

Bash 变量可以具有全局或局部作用域。无论范围如何,您都可以在 bash 脚本中的任何位置访问全局变量。相反,局部变量只能从它们的函数定义中访问。

为了演示,请查看以下linuxmi.com.sh bash 脚本:

#!/bin/bash
#Linux迷 www.linuxmi.com
a1='X'
a2='Y'

myfun() {
local v1='Z'
v2='W'
echo "Inside myfun(): a1: $a1, a2: $a2"
}

echo "Before calling myfun(): v1: $a1, a2: $a2"
myfun
echo "After calling myfun(): a1: $a1, a2: $a2"

我首先定义了两个全局变量a1a2。然后在myfun()定义中,我使用local关键字定义了一个局部变量a1并修改了全局变量a2。请注意,您可以为不同函数中的局部变量使用相同的变量名。

现在让我们运行脚本:

从脚本输出中,您可以得出以下结论:

  • 与全局变量同名的局部变量将优先于函数体内的全局变量。
  • 您可以从函数内更改全局变量。

递归函数

递归函数是一个调用自身的函数!当您尝试解决可以分解为更小的子问题的编程问题时,递归函数会派上用场。

阶乘函数是递归函数的一个典型例子。查看以下 linuxmi.com.sh bash 脚本:

#!/bin/bash
#Linux迷 www.linuxmi.com
factorial () {
if [ $1 -le 1 ]; then
echo 1
else
last=$(factorial $(( $1 -1)))
echo $(( $1 * last ))
fi
}

echo -n "4! is: "
factorial 4
echo -n "5! is: "
factorial 5
echo -n "6! is: "
factorial 6

任何递归函数都必须以一个基本情况开始,该基本情况必然会结束递归函数调用链。在factorial()函数中,基本情况定义如下:

if [ $1 -le 1 ]; then
echo 1

现在推导阶乘函数的递归情况。要计算数字n的阶乘,其中n是大于 1 的正数,您可以将n乘以n-1的阶乘:

factorial(n) = n * factorial(n-1)

让我们使用上面的等式来编写这个递归案例:

last=$(factorial $(( $1 -1)))
echo $(( $1 * last ))

现在运行脚本并确保获得正确的结果:

作为附加练习,尝试编写一个递归函数来计算第 n 个斐波那契数。首先,尝试提出基本情况,然后提出递归情况;你明白了!

The post Bash 初学者系列 #1:在 Bash 中使用函数 first appeared on Linux迷.

版权声明:
作者:感冒的梵高
链接:https://www.techfm.club/p/40250.html
来源:TechFM
文章版权归作者所有,未经允许请勿转载。

THE END
分享
二维码
< <上一篇
下一篇>>