Shell 函数基础

ShellBeginner
立即练习

简介

编写脚本时,你经常需要多次重复执行同一段代码。与其反复重写或复制粘贴,不如使用函数。

函数是一段具有名称、用于执行特定任务的代码块。你只需定义一次,就可以在需要时随时调用。这样可以让脚本具备以下特点:

  • 模块化:更易于阅读和管理。
  • 可复用:编写一次,多次使用。
  • 易维护:需要修改逻辑时,只需在一个位置更新。

函数非常重要,因为当所有代码都集中在一个从上到下的长代码块中时,大型脚本会变得难以理解。将脚本拆分为多个函数,是从「临时 Shell 脚本」迈向「可维护自动化」的第一步之一。

在本实验中,你将学习如何使用函数重写脚本的基础知识。你将完成以下任务:

  1. 创建一个基础脚本。
  2. 定义一个名为 greet_user 的函数。
  3. 调用该函数来执行它。
  4. 改进该函数,使其能够接收参数。

创建脚本文件

先设置工作环境。我们将创建一个名为 functions.sh 的文件,用于保存代码。

此时,脚本文件还只是一个容器。本实验的重点不在于文件本身,而在于理解:脚本可以组织成多个具有名称的代码片段,而不是只有一个从头执行到尾的长代码块。

先进入项目目录并创建文件:

cd ~/project
touch functions.sh

接着,在文本编辑器中打开文件,添加标准的 Shebang 头部:

nano functions.sh

在文件顶部添加以下内容:

#!/bin/bash

保存文件(Ctrl+O,然后按 Enter),再退出(Ctrl+X)。

最后,为脚本添加可执行权限,以便稍后运行:

chmod +x functions.sh

现在可以开始编写代码了。

定义函数

现在定义一个名为 greet_user 的函数。

在 Bash 中,定义函数时,要先写函数名和括号 (),再使用花括号 {} 包围代码块。

函数为一组命令提供了一个可复用的名称。这可以提高 Shell 脚本的可读性:你不再只能看到分散的原始命令,而是可以看到 backup_files、check_disk 或 greet_user 这类具有明确含义的操作名称。

语法如下:

function_name() {
  ## Commands to execute
}

再次打开脚本:

nano functions.sh

在 Shebang 行下方添加以下函数定义:

#!/bin/bash

greet_user() {
  echo "Hello"
}

重要提示:此时我们只是定义了函数,还没有告诉脚本实际执行它。如果现在运行脚本,不会产生任何结果。初学者经常会对此感到困惑:定义函数不会自动执行函数。

之所以要区分这两点,是因为 Shell 脚本会按照顺序读取并执行。函数定义只是让 Bash 知道这个函数的含义;只有稍后调用函数名时,函数体中的代码才会执行。

暂时保存并退出。

调用函数

要执行函数中的代码,必须「调用」函数。在 Bash 中,只需在新的一行写出函数名即可调用函数。调用时不需要使用括号。

对于初学者来说,这种写法可能不太直观,因为许多编程语言会在调用函数时使用括号。在 Bash 中,单独出现的 greet_user 会被当作一条命令。如果存在同名函数,Bash 就会执行该函数体。

打开脚本:

nano functions.sh

在文件底部添加函数调用:

#!/bin/bash

greet_user() {
  echo "Hello"
}

## The Main Logic starts here
greet_user

保存并退出。

现在运行脚本:

./functions.sh

脚本运行时,Shell 会看到 greet_user 命令,找到函数定义,执行 echo "Hello",然后继续执行后续内容。

从这个角度看,函数很像一个自定义命令,只存在于当前脚本或当前 Shell 会话中。这正是函数非常有用的原因:你可以使用更小的 Shell 命令构建更高层次的操作。

你应该会看到以下输出:

Hello

向函数传递参数

如果一个函数始终执行完全相同的操作,例如输出 Hello,它的用途会受到限制。为了让函数更加实用,我们可以向其中传入数据。这些数据称为参数。

在函数内部,你可以使用 $1、$2 等特殊变量访问参数,就像访问脚本参数一样。

  • $1 表示传递给函数的第一个参数。
  • $2 表示传递给函数的第二个参数,依此类推。

这些参数与函数运行时脚本自身的位置参数相互独立。换句话说,函数可以拥有自己的输入接口,因此能够使用不同的值重复调用。

下面修改函数,让它向指定名称打招呼。

步骤 1:更新函数定义

打开文件:

nano functions.sh

修改 greet_user 函数,让它使用 $1,而不是使用固定字符串:

greet_user() {
  echo "Hello $1"
}

步骤 2:更新函数调用

现在函数需要一个参数,因此调用函数时必须提供参数。

将调用语句从 greet_user 改为 greet_user "LabEx"。

此时文件内容应如下所示:

#!/bin/bash

greet_user() {
  echo "Hello $1"
}

greet_user "LabEx"

保存并退出。

步骤 3:测试脚本

再次运行脚本:

./functions.sh

此时输出应为:

Hello LabEx

实际上,你已经创建了一个能够接收输入并处理输入的自定义命令。稍后你可以在脚本中调用 greet_user "Alice" 或 greet_user "Bob",函数会根据传入的名称输出相应内容。

总结

在本实验中,你学习了 Bash 函数的基础知识:

  1. 定义函数:使用 name() { ... } 创建具有名称的代码块。
  2. 调用函数:直接输入函数名来执行函数。
  3. 传递参数:向函数传入数据,并通过 $1、$2 等变量访问这些数据。

函数是构建复杂脚本的基础。它们可以帮助你组织逻辑、减少重复,并让代码更易于阅读和维护。