创建 Bash 脚本模板

在本系列的第二篇文章中,创建一个相当简单的模板,你可以将其用作其他 Bash 程序的起点,然后对其进行测试。
131 位读者喜欢此文。
Jump-start your career with open source skills

Opensource.com

在本系列的第一篇文章中,你创建了一个非常小的单行 Bash 脚本,并探讨了创建 shell 脚本的原因,以及为什么它们对于系统管理员来说是最有效的选择,而不是编译的程序。

在这第二篇文章中,你将开始创建一个 Bash 脚本模板,该模板可以用作其他 Bash 脚本的起点。该模板最终将包含一个帮助工具、一个许可声明、一些简单的函数以及一些用于处理这些选项以及其他可能基于此模板的脚本所需的逻辑。

为什么要创建模板?

与一般自动化一样,创建模板背后的想法是成为“懒惰的系统管理员”。模板包含你希望在所有脚本中包含的基本组件。 与将这些组件添加到每个新脚本相比,它可以节省时间,并且可以轻松启动新脚本。

虽然将一些命令行 Bash 语句一起放入文件中并使其可执行可能很诱人,但从长远来看,这可能会适得其反。 一个编写良好且注释充分的 Bash 程序,具有帮助工具和接受命令行选项的功能,为维护该程序的系统管理员提供了一个良好的起点,其中包括 *你* 编写和维护的程序。

要求

你应该始终为所做的每个项目创建一组要求。 这包括脚本,即使它只是一个简单的列表,上面只有两三个项目。 我参与过许多完全失败或未能满足客户需求的项目,通常是由于缺乏需求说明或编写不佳的需求说明造成的。

此 Bash 模板的要求非常简单

  1. 创建一个可用作未来 Bash 编程项目起点的模板。
  2. 该模板应遵循标准的 Bash 编程实践。
  3. 它必须包括
    • 一个标题部分,可用于描述程序的功能和变更日志
    • 许可声明
    • 一个函数部分
    • 一个帮助函数
    • 一个测试程序用户是否为 root 的函数
    • 一种评估命令行选项的方法

基本结构

基本的 Bash 脚本有三个部分。 Bash 没有办法来描绘部分,但是部分之间的边界是隐含的。

  • 所有脚本都必须以 shebang (#!) 开头,并且这必须是任何 Bash 程序的第一行。
  • 函数部分必须在 shebang 之后和程序主体之前开始。 作为我记录一切的需求的一部分,我在每个函数之前放置一个注释,其中包含对其预期用途的简短描述。 我还在函数内部包含注释以进一步阐述。 简短、简单的程序可能不需要函数。
  • 程序的主要部分在函数部分之后。 这可以是一个简单的 Bash 语句,也可以是数千行代码。 我的一个程序有 200 多行代码,不包括注释。 同一个程序有 600 多行注释。

这就是全部 - 任何 Bash 程序的结构中只有三个部分。

前导注释

我总是出于各种原因添加更多内容。 首先,我在 shebang 之后立即添加几个注释部分。 这些注释部分是可选的,但我发现它们非常有用。

第一个注释部分是程序名称和描述以及更改历史记录。 我在 IBM 工作时学到了这种格式,它提供了一种记录程序的长期开发和应用于它的任何修复的方法。 这是记录程序的重要开始。

第二个注释部分是版权和许可声明。 我使用 GPLv2,这似乎是根据 GPLv2 许可的程序的标准声明。 如果你使用不同的开源许可证,那没关系,但我建议在代码中添加明确的声明,以消除关于许可的任何可能的混淆。 Scott Peterson 的文章源代码就是许可证有助于解释这背后的原因。

所以现在脚本看起来像这样

#!/bin/bash
################################################################################
#                              scriptTemplate                                  #
#                                                                              #
# Use this template as the beginning of a new program. Place a short           #
# description of the script here.                                              #
#                                                                              #
# Change History                                                               #
# 11/11/2019  David Both    Original code. This is a template for creating     #
#                           new Bash shell scripts.                            #
#                           Add new history entries as needed.                 #
#                                                                              #
#                                                                              #
################################################################################
################################################################################
################################################################################
#                                                                              #
#  Copyright (C) 2007, 2019 David Both                                         #
#  LinuxGeek46@both.org                                                        #
#                                                                              #
#  This program is free software; you can redistribute it and/or modify        #
#  it under the terms of the GNU General Public License as published by        #
#  the Free Software Foundation; either version 2 of the License, or           #
#  (at your option) any later version.                                         #
#                                                                              #
#  This program is distributed in the hope that it will be useful,             #
#  but WITHOUT ANY WARRANTY; without even the implied warranty of              #
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               #
#  GNU General Public License for more details.                                #
#                                                                              #
#  You should have received a copy of the GNU General Public License           #
#  along with this program; if not, write to the Free Software                 #
#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA   #
#                                                                              #
################################################################################
################################################################################
################################################################################

echo "hello world!"

运行修改后的程序以验证它是否仍然按预期工作。

关于测试

现在是谈论测试的好时机。

总会多一个 bug。”

— Lubarsky 的控制论昆虫学定律

Lubarsky——无论他是谁——是正确的。 你永远无法找到代码中的所有 bug。 对于我发现的每一个 bug,似乎总会有另一个 bug 出现,通常是在非常不合时宜的时候。

测试不仅仅是关于程序。 它还关于验证应该解决的问题(无论是硬件、软件还是用户可以找到的破坏事物的方式)是否真正得到解决。 同样重要的是,测试还关于确保代码易于使用,并且界面对用户来说是有意义的。

在编写和测试 shell 脚本时遵循明确定义的过程可以产生一致且高质量的结果。 我的过程很简单

  1. 创建一个简单的测试计划。
  2. 在开发一开始就进行测试。
  3. 代码完成后执行最终测试。
  4. 转移到生产并进行更多测试。

测试计划

测试计划有很多不同的格式。 我已经使用过各种各样的格式——从将所有内容都记在脑海中; 到在一张纸上记下一些笔记; 一直到一套复杂的形式,需要对每个测试进行完整的描述,包括它将测试哪个功能代码,测试将完成什么,以及输入和结果应该是什么。

作为一名曾经(但现在不是)测试员的系统管理员,我尽量采取中间立场。 至少有一个简短的书面测试计划将确保从一个测试运行到下一个测试运行的一致性。 你需要多少细节取决于你的开发和测试功能有多正式。

我使用 Google 找到的示例测试计划文档很复杂,旨在用于具有非常正式的开发和测试流程的大型组织。 虽然这些测试计划对那些工作头衔中带有“测试”的人来说会很好,但它们并不适用于系统管理员更加混乱和时间依赖的工作条件。 与工作中其他大多数方面一样,系统管理员需要具有创造力。 因此,这里有一个简短的列表,其中包含在测试计划中要考虑包含的内容。 修改它以满足你的需求

  • 被测软件的名称和简短描述
  • 要测试的软件功能的描述
  • 每个测试的起始条件
  • 每个测试要遵循的函数
  • 每个测试所需结果的描述
  • 旨在测试负面结果的特定测试
  • 程序如何处理意外输入的测试
  • 对每个测试构成通过或失败的明确描述
  • 模糊测试,如下所述

此列表应该为你创建测试计划提供一些想法。 大多数系统管理员应该保持简单和相当非正式。

尽早测试 - 经常测试

我总是在完成第一个可执行的部分后立即开始测试我的 shell 脚本。 无论我是编写一个简短的命令行程序还是一个作为可执行文件的脚本,都是如此。

我通常从 shell 脚本模板开始创建新程序。 我编写帮助函数的代码并进行测试。 这通常是该过程的一个微不足道的部分,但它可以帮助我入门并确保模板中的内容在一开始就能正常工作。 此时,很容易修复脚本的模板部分中的问题或修改它以满足标准模板无法满足的需求。

一旦模板和帮助函数工作正常,我就继续创建程序的主体,方法是添加注释以记录满足程序规范所需的编程步骤。 现在我开始添加代码以满足每个注释中规定的要求。 此代码可能需要添加在该模板部分中初始化的变量,该模板现在正在成为 shell 脚本。

这里测试不仅仅是输入数据和验证结果。它需要额外的工作。有时我会添加一个命令,简单地打印我刚写的代码的中间结果并进行验证。对于更复杂的脚本,我会添加一个 -t 选项,表示“测试模式”。在这种情况下,内部测试代码仅在命令行输入 -t 选项时执行。

最终测试

代码完成后,我会返回来对所有特性和功能进行完整的测试,使用已知的输入来产生特定的输出。我还会测试一些随机输入,看看程序是否能处理意外的输入。

最终测试旨在验证程序是否基本上按预期运行。最终测试的一个重要部分是确保在开发周期早期工作的功能没有被后期添加或更改的代码破坏。

如果你在添加新代码时一直在测试脚本,你可能认为在最终测试中不应该有任何意外。 错了! 最终测试总是会有意外。 总是如此。 期待这些意外,并准备好花时间修复它们。 如果在最终测试中从未发现任何错误,那么进行最终测试就没有意义了,不是吗?

生产环境中的测试

哈—什么?

“只有当一个程序在生产环境中运行至少六个月后,才会发现最有害的错误。”

— Troutman 编程假设

是的,现在认为在生产环境中进行测试是正常且可取的。 作为一名测试人员,这似乎很合理。 “等等! 这很危险,” 你说。 我的经验是,它与在专用测试环境中进行广泛而严格的测试一样危险。 在某些情况下,别无选择,因为没有测试环境——只有生产环境。

系统管理员对在生产环境中测试新的或修改的脚本的需求并不陌生。 任何时候将脚本移到生产环境,那就是最终的测试。 生产环境构成了该测试最关键的部分。 测试人员在测试环境中设想的任何东西都无法完全复制真实的生产环境。

所谓新的生产环境测试实践只是对系统管理员一直都知道的事情的认可。 最好的测试是生产环境——只要它不是唯一的测试。

模糊测试

这是另一个最初让我翻白眼的流行语。 它的基本含义很简单:让某人敲打键盘直到发生某些事情,并看看程序处理得如何。 但实际上,它不仅仅如此。

模糊测试有点像我的儿子在不到一分钟的时间内用随机输入破坏了一个游戏的代码。 这几乎结束了我为他编写游戏的尝试。

大多数测试计划利用非常具体的输入来生成特定的结果或输出。 无论测试是将正面还是负面结果定义为成功,它仍然是受控的,并且输入和结果是指定和预期的,例如针对特定故障模式的特定错误消息。

模糊测试是关于处理测试各个方面的随机性,例如启动条件、非常随机和意外的输入、随机选择的选项组合、低内存、CPU 与其他程序争用的高水平、被测程序的多个实例以及你可以想到的任何其他随机条件来应用于测试。

我尝试从一开始就进行一些模糊测试。 如果 Bash 脚本在非常早期的阶段无法处理显着的随机性,那么随着你添加更多代码,它不太可能会变得更好。 这是在代码相对简单时发现并修复这些问题的好时机。 在每个阶段进行一些模糊测试也有助于在问题被更多代码掩盖之前找到它们。

代码完成后,我喜欢做一些更广泛的模糊测试。 务必进行一些模糊测试。 我确实对某些结果感到惊讶。 测试预期的事情很容易,但用户通常不会使用脚本做预期的事情。

即将推出的预览

本文在创建模板方面取得了一些成就,但主要讨论了测试。 这是因为测试是创建任何类型程序的重要组成部分。 在本系列的下一篇文章中,你将添加一个基本的 Help 函数,以及一些代码来检测和处理选项,例如 -h,到你的 Bash 脚本模板。

资源


本系列文章部分基于 David Both 的三部分 Linux 自学课程《使用和管理 Linux—从零到系统管理员》的第 2 卷第 10 章。

接下来要阅读什么

Bash 脚本自动化入门

在本系列四部分文章的第一篇中,学习如何创建简单的 Shell 脚本以及它们为什么是自动化任务的最佳方式。

标签
David Both
David Both 是开源软件和 GNU/Linux 的倡导者、培训师、作家和演讲者。 他自 1996 年以来一直在使用 Linux 和开源软件,自 1969 年以来一直在使用计算机。 他是“系统管理员的 Linux 哲学”的坚定支持者和传播者。

评论已关闭。

Creative Commons License本作品已获得 Creative Commons Attribution-Share Alike 4.0 International License 许可。
© . All rights reserved.