在本系列的第一篇文章中,你创建了你的第一个非常小的单行 Bash 脚本,并探索了创建 shell 脚本的原因。在第二篇文章中,你开始创建一个相当简单的模板,它可以作为其他 Bash 程序的起点,并开始对其进行测试。在第三篇文章中,你创建并使用了简单的帮助函数,并学习了如何使用函数以及如何处理命令行选项,例如 -h。
本系列文章的第四篇也是最后一篇文章深入探讨了变量和初始化变量,以及如何进行一些健全性测试,以帮助确保程序在适当的条件下运行。请记住,本系列文章的目标是构建可用于未来 Bash 编程项目的模板的工作代码。其想法是通过在模板中预先提供常用元素,使开始新的编程项目变得容易。
变量
Bash shell 像所有编程语言一样,可以处理变量。变量是一个符号名称,它指向内存中的特定位置,该位置包含某种类型的值。变量的值是可变的,即它是可变的。如果你不熟悉使用变量,请在继续之前阅读我的文章如何使用 Bash 进行编程:语法和工具。
完成了?太棒了!现在让我们看看使用变量时的一些良好实践。
我总是为我的脚本中使用的每个变量设置初始值。你可以在你的模板脚本中的过程之后立即找到它,作为主程序体的第一部分,在它处理选项之前。使用适当的值初始化每个变量可以防止在比较或数学运算中使用未初始化变量时可能发生的错误。将此变量列表放在一个位置可以让你看到脚本中应该存在的所有变量及其初始值。
到目前为止,你的小程序只有一个变量 $option。通过插入以下行来设置它,如图所示
################################################################################
################################################################################
# Main program #
################################################################################
################################################################################
# Initialize variables
option=""
################################################################################
# Process the input options. Add options as needed. #
################################################################################
测试这个以确保一切正常工作,并且没有任何东西因这个更改而损坏。
常量
常量也是变量——至少它们应该是。在命令行界面 (CLI) 程序中,尽可能使用变量而不是硬编码值。即使你认为你只会使用一次特定值(例如目录名称、文件名或文本字符串),也要创建一个变量并在你放置硬编码名称的地方使用它。
例如,作为程序主体一部分打印的消息是一个字符串文字,echo "Hello world!"。将其更改为变量。首先,将以下语句添加到变量初始化部分
Msg="Hello world!"
现在将程序的最后一行从
echo "Hello world!"
更改为
echo "$Msg"
测试结果。
健全性检查
健全性检查只是对程序要正确工作需要为真的条件进行测试,例如:程序必须以 root 用户身份运行,或者它必须在特定发行版和该发行版的版本上运行。在你的简单程序模板中添加对以 root 作为运行用户的检查。
测试 root 用户正在运行程序很容易,因为程序以启动它的用户身份运行。
id 命令可用于确定程序正在其下运行的数字用户 ID (UID)。当不使用任何选项时,它提供一些信息
[student@testvm1 ~]$ id
uid=1001(student) gid=1001(student) groups=1001(student),5000(dev)
使用 -u 选项仅返回用户的 UID,这在你的 Bash 程序中很容易使用
[student@testvm1 ~]$ id -u
1001
[student@testvm1 ~]$
将以下函数添加到程序中。我将其添加到帮助过程之后,但你可以将其放在过程部分的任何位置。逻辑是,如果 UID 不为零(始终是 root 用户的 UID),则程序退出
################################################################################
# Check for root. #
################################################################################
CheckRoot()
{
if [ `id -u` != 0 ]
then
echo "ERROR: You must be root user to run this program"
exit
fi
}
现在,在变量初始化之前添加对 CheckRoot 过程的调用。首先以学生用户身份运行程序来测试它
[student@testvm1 ~]$ ./hello
ERROR: You must be root user to run this program
[student@testvm1 ~]$
然后以 root 用户身份运行
[root@testvm1 student]# ./hello
Hello world!
[root@testvm1 student]#
你可能并不总是需要这个特定的健全性测试,因此注释掉对 CheckRoot 的调用,但将所有代码保留在模板中。这样,你只需取消注释调用即可在未来的程序中使用该代码。
代码
在进行上述更改后,你的代码应如下所示
#!/usr/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 #
# #
################################################################################
################################################################################
################################################################################
################################################################################
# Help #
################################################################################
Help()
{
# Display Help
echo "Add description of the script functions here."
echo
echo "Syntax: scriptTemplate [-g|h|v|V]"
echo "options:"
echo "g Print the GPL license notification."
echo "h Print this Help."
echo "v Verbose mode."
echo "V Print software version and exit."
echo
}
################################################################################
# Check for root. #
################################################################################
CheckRoot()
{
# If we are not running as root we exit the program
if [ `id -u` != 0 ]
then
echo "ERROR: You must be root user to run this program"
exit
fi
}
################################################################################
################################################################################
# Main program #
################################################################################
################################################################################
################################################################################
# Sanity checks #
################################################################################
# Are we rnning as root?
# CheckRoot
# Initialize variables
option=""
Msg="Hello world!"
################################################################################
# Process the input options. Add options as needed. #
################################################################################
# Get the options
while getopts ":h" option; do
case $option in
h) # display Help
Help
exit;;
\?) # incorrect option
echo "Error: Invalid option"
exit;;
esac
done
echo "$Msg"
最后的练习
你可能已经注意到,你的代码中的帮助函数引用了代码中不存在的功能。作为最后的练习,弄清楚如何将这些函数添加到你创建的代码模板中。
总结
在本文中,你创建了几个函数来执行健全性测试,以检查你的程序是否以 root 身份运行。你的程序变得稍微复杂了一些,因此测试变得更加重要,并且需要更完整的测试路径。
本系列文章着眼于一个非常小的 Bash 程序,以及如何一次构建一点脚本。结果是一个简单的模板,它可以作为其他更有用的 Bash 脚本的起点,并且包含有用的元素,使其易于启动新脚本。
到现在为止,你已经明白了:编译后的程序是必要的,并且满足了非常重要的需求。但对于系统管理员来说,总有更好的方法。始终使用 shell 脚本来满足你工作的自动化需求。Shell 脚本是开放的;它们的内容和目的都是可知的。它们可以很容易地被修改以满足不同的需求。我从未发现我在系统管理员角色中需要做的任何事情不能用 shell 脚本完成。
到目前为止,你在本系列中创建的只是一个开始。随着你编写更多的 Bash 程序,你会发现更多你经常使用的代码片段,这些代码片段应该包含在你的程序模板中。
资源
本系列文章部分基于 David Both 的三部分 Linux 自学课程《使用和管理 Linux—从零到系统管理员》的第 2 卷第 10 章。
评论已关闭。