Linux Shell核心编程指南
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

2.7 实战案例:单分支if语句

对于简单的条件判断,结合&&和||就可以完成大量的脚本。但是当脚本越写越复杂、功能越写越完善时,简单的&&和||就不足以满足需求了。

此时,选择使用if语句结合各种判断条件,功能会更加完善和强大。在Shell脚本中if语句有三种格式,分别是单分支if语句、双分支if语句和多分支if语句。下面是单分支if语句的语法格式。

if 条件测试
then
    命令序列
fi

if和then可以写在同一行。同一行中如果需要编写多条命令,中间需要使用分号分隔命令。所以,单分支if语句也可以写成如下格式。

if条件测试;then
    命令序列
Fi

单分支if语句会检查条件测试的结果,只要返回的结果为真,那么就会执行then后面的命令序列(可以包含一条或多条命令)。但如果测试条件返回的结果为假,那么if语句就什么命令也不执行。这里的条件测试除了可以是字符串的比较测试、数字的比较测试、文件或目录属性的测试,还可以是一条或多条命令。单分支if语句的工作流程如图2-1所示。

图2-1 单分支if语句的工作流程

下面我们看一个单分支if语句的例子,读取用户输入的用户名和密码后,脚本通过if判断用户名和密码是否非空,如果非空则创建账户并设置密码,否则脚本直接结束。执行脚本,当提示输入用户名和密码时,如果我们都不输入(直接按回车键),脚本就会退出。

但是,上面的脚本有一个问题。当执行脚本提示输入用户名时,直接按回车键,而当提示输入密码时,正常输入一个密码,这时运行脚本就会报错。因为这样导致在账户没有创建成功的情况下,修改账户密码,结果一定会报错。因此,还需要继续优化这个脚本,可以使用嵌套if语句(在if语句里面再使用if语句)来解决该问题。

这样做的好处是,如果账户名为空,则脚本就不会执行then后面的命令,也就不会对密码做任何测试动作,更不会修改账户密码,而是直接退出脚本。如果测试账户名为非空,则进一步对密码进行测试,如果密码也非空,那么就执行then后的命令,创建账户并设置密码。

因为在学习前面的测试语句时,可以同时对多个条件进行测试,所以上面的脚本可以继续修改为下面的版本。

或者,下面这样的版本。

又或者,下面这样的版本。虽然在[]中不允许使用&&和||符号进行多个条件的测试判断,但是,可以使用多次[]测试,中间使用&&和||进行逻辑判断。

提示:if语句后面的条件测试语句不一定非要是test或[]测试语句,任何有返回值的命令都可以写在if语句后面,命令返回值为0代表执行成功(即为真),返回值非0代表执行失败(即为假)。下面看案例。

脚本自动测试,如果某些操作无法完成则报错,这是很常用的脚本功能。

下面这个例子,可以通过if条件语句自动判断服务的各种状态,是否已经启动、是否为开机自启动项等。

下面介绍如何一键创建VNC服务器脚本。

如果你的Linux服务器有图形环境,而你又希望将自己的屏幕共享给其他人,这样就可以在没有投影设备的情况下,让其他人看到你的屏幕操作了。下面是一键配置VNC远程桌面的脚本案例。

在Linux系统中tigervnc-server软件可提供远程桌面服务,脚本首先检查系统中是否已经存在该软件。如果不存在,则脚本自动安装该软件。安装软件后,通过x0vncserver命令创建远程桌面服务,该命令的选项功能描述如下。

● AcceptKeyEvents=0,禁止其他人在远程操作本机时使用键盘。设置为1时,表示允许操作键盘。默认值为1。

● AcceptPointerEvents=0,禁止其他人在远程操作本机时使用鼠标。设置为1时,表示允许操作鼠标。默认值为1。

● AlwaysShared=1,当有多人远程操作本机时,永远支持共享。设置为0时,同时仅允许一个人远程操作本机。默认值为0。

● SecurityTypes=None,当其他人远程操作本机时,不需要输入密码。也可以设置为需要输入密码的方式连接本机。默认值为VncAuth,需要输入密码认证。

● rfbport=5908,设置远程桌面连接的端口号为5908,也可以设置为其他端口号。

配置完VNC服务器后,客户端可以通过下面的命令查看远程桌面。

[root@centos7~]# yum -y install tigervnc
[root@centos7~]# vncviewer 服务器的IP地址:5908

2.8 实战案例:双分支if语句

与单分支if语句的格式一样,then和if可以写在同一行,也可以分开写在不同行。甚至在else和命令序列1中间添加分号将其写在同一行,但很少有人这样写,这将导致代码的可读性非常差。

if条件测试;then
    命令序列1
else
    命令序列2
Fi

双分支if语句会检查条件测试的结果,只要测试条件返回值结果为真,就会执行命令序列1(可以包含一条或多条命令)。但如果测试条件返回值结果为假,那么就会执行命令序列2。所以双分支if语句,不管条件是否成立,都会执行特定的命令。双分支if语句的工作流程如图2-2所示。

图2-2 双分支if语句的工作流程

看一个简单的双分支if语句的例子,使用if语句判断某台主机是否可以ping通。这是一个典型的双分支if语句案例。

因为RPM等类似的二进制软件往往不能提供最新的版本,并且不具备自定义安装选项,所以生产环境中经常需要采用源码的方式安装软件。但采用源码的方式安装软件的步骤又比较烦琐,所以编写脚本实现自动化安装软件是非常重要的。下面看一个采用源码的方式安装软件的脚本案例。

脚本解析如下。

脚本的第一个功能是通过使用变量的方式,定义echo回显的颜色属性。echo命令的-n选项,可以在回显数据后不按回车键即可换行,-e选项开启右斜线(\)转义的解释功能。

通过对系统环境变量UID的比较测试,判断当前执行脚本的用户是否为管理员。如果不是管理员,则脚本直接提示错误并退出。

使用rpm -q可以查询某个软件是否已经安装。再通过--quiet选项,设置无论软件是否已经安装都不在屏幕上回显结果,而是通过if语句自动判断命令的执行结果是真还是假。如果未安装wget,则脚本提示错误并退出。反之,在系统中已有wget工具的情况下,联网下载Nginx源码包软件.注意:官网提供的Nginx下载链接地址可能会有变化,如果有改变,可以直接去官网找最新的下载链接。。wget命令的-c选项可以开启断点续传的功能,下载过程中如果突然断网,联网后可以从上次的断点处继续下载,而不需要将文件全部重新下载。

启动Nginx服务时,以普通用户的身份登录会更安全。脚本通过Id命令检查nginx账户是否已经存在,如果不存在nginx账户,则脚本会自动创建该账户。

在编译源码安装Nginx时,首先需要安装该软件包依赖的相关软件包,脚本中安装了gcc、pcre-devel、zlib-devel、openssl-devel这四个软件包,这些软件都在CentOS标准的Yum中,并且在安装openssl-devel时会自动安装zlib-devel。所以,哪怕不通过Yum明确要求安装zlib-devel,也会在安装openssl-devel时自动安装zlib-devel。Nginx是模块化的软件,可以通过<--with-模块>的方式启动某个模块的功能,不需要的功能模块,可以通过<--without-模块>的方式禁用。