鸟哥的 Linux 私房菜

您所在的位置:网站首页 bash命令最简单三个步骤 鸟哥的 Linux 私房菜

鸟哥的 Linux 私房菜

2024-07-17 19:40| 来源: 网络整理| 查看: 265

第十三章、学习 Shell Scripts 最近升级日期:2009/02/18 如果你真的很想要走资讯这条路,并且想要管理好属於你的主机,那么,别说鸟哥不告诉你, 可以自动管理系统的好工具: Shell scripts!这家伙真的是得要好好学习学习的! 基本上, shell script 有点像是早期的批量档,亦即是将一些命令汇整起来一次运行,但是 Shell script 拥有更强大的功能,那就是他可以进行类似程序 (program) 的撰写,并且不需要经过编译 (compile) 就能够运行, 真的很方便。加上我们可透过 shell script 来简化我们日常的工作管理, 而且,整个 Linux 环境中,一些服务 (services) 的启动都是透过 shell script 的, 如果你对於 script 不了解,嘿嘿!发生问题时,可真是会求助无门喔!所以,好好的学一学他吧! 1. 什么是 Shell Script   1.1 干嘛学习 shell scripts   1.2 第一支 script 的撰写与运行   1.3 撰写 shell script 的良好习惯创建 2. 简单的 shell script 练习   2.1 简单范例: 对谈式脚本, 随日期变化, 数值运算   2.2 script 的运行方式差异 (source, sh script, ./script) 3. 善用判断式   3.1 利用 test 命令的测试功能   3.2 利用判断符号 [ ]   3.3 Shell script 的默认变量($0, $1...): shift 4. 条件判断式   4.1 利用 if .... then: 单层简单条件, 多重复杂条件, 检验$1内容, 网络状态, 退伍   4.2 利用 case ..... esac 判断   4.3 利用 function 功能 5. 回圈 (loop)   5.1 while...do...done, until...do...done (不定回圈)   5.2 for...do...done (固定回圈): 帐号检查, 网络状态 $(seq )   5.3 for...do...done 的数值处理 6. shell script 的追踪与 debug 7. 重点回顾 8. 本章习题 9. 参考数据与延伸阅读 10. 针对本文的建议:http://phorum.vbird.org/viewtopic.php?t=23886 什么是 Shell scripts

什么是 shell script (程序化脚本) 呢?就字面上的意义,我们将他分为两部份。 在『 shell 』部分,我们在 十一章的 BASH 当中已经提过了,那是一个文字介面底下让我们与系统沟通的一个工具介面。那么『 script 』是啥? 字面上的意义, script 是『脚本、剧本』的意思。整句话是说, shell script 是针对 shell 所写的『剧本!』

什么东西啊?其实, shell script 是利用 shell 的功能所写的一个『程序 (program)』,这个程序是使用纯文字档,将一些 shell 的语法与命令(含外部命令)写在里面, 搭配正规表示法、管线命令与数据流重导向等功能,以达到我们所想要的处理目的。

所以,简单的说, shell script 就像是早期 DOS 年代的批量档 (.bat) ,最简单的功能就是将许多命令汇整写在一起, 让使用者很轻易的就能够 one touch 的方法去处理复杂的动作 (运行一个文件 "shell script" ,就能够一次运行多个命令)。 而且 shell script 更提供阵列、回圈、条件与逻辑判断等重要功能,让使用者也可以直接以 shell 来撰写程序,而不必使用类似 C 程序语言等传统程序撰写的语法呢!

这么说你可以了解了吗?是的! shell script 可以简单的被看成是批量档, 也可以被说成是一个程序语言,且这个程序语言由於都是利用 shell 与相关工具命令, 所以不需要编译即可运行,且拥有不错的除错 (debug) 工具,所以,他可以帮助系统管理员快速的管理好主机。

干嘛学习 shell scripts

这是个好问题:『我又干嘛一定要学 shell script ?我又不是资讯人,没有写程序的概念, 那我干嘛还要学 shell script 呢?不要学可不可以啊?』呵呵~如果 Linux 对你而言, 你只是想要『会用』而已,那么,不需要学 shell script 也还无所谓,这部分先给他跳过去, 等到有空的时候,再来好好的瞧一瞧。但是,如果你是真的想要玩清楚 Linux 的来龙去脉, 那么 shell script 就不可不知,为什么呢?因为:

自动化管理的重要依据:

不用鸟哥说你也知道,管理一部主机真不是件简单的事情,每天要进行的任务就有: 查询登录档、追踪流量、监控使用者使用主机状态、主机各项硬件设备状态、 主机软件升级查询、更不要说得应付其他使用者的突然要求了。而这些工作的进行可以分为: (1)自行手动处理,或是 (2)写个简单的程序来帮你每日自动处理分析这两种方式,你觉得哪种方式比较好? 当然是让系统自动工作比较好,对吧!呵呵~这就得要良好的 shell script 来帮忙的啦!

追踪与管理系统的重要工作:

虽然我们还没有提到服务启动的方法,不过,这里可以先提一下,我们 Linux 系统的服务 (services) 启动的介面是在 /etc/init.d/ 这个目录下,目录下的所有文件都是 scripts ; 另外,包括启动 (booting) 过程也都是利用 shell script 来帮忙搜寻系统的相关配置数据, 然后再代入各个服务的配置参数啊!举例来说,如果我们想要重新启动系统登录档, 可以使用:『/etc/init.d/syslogd restart』,那个 syslogd 文件就是 script 啦!

另外,鸟哥曾经在某一代的 Fedora 上面发现,启动 MySQL 这个数据库服务时,确实是可以启动的, 但是萤幕上却老是出现『failure』!后来才发现,原来是启动 MySQL 那个 script 会主动的以『空的密码』去尝试登陆 MySQL ,但为了安全性鸟哥修改过 MySQL 的密码罗~当然就登陆失败~ 后来改了改 script ,就略去这个问题啦!如此说来, script 确实是需要学习的啊!

简单入侵侦测功能:

当我们的系统有异状时,大多会将这些异状记录在系统记录器,也就是我们常提到的『系统登录档』, 那么我们可以在固定的几分钟内主动的去分析系统登录档,若察觉有问题,就立刻通报管理员, 或者是立刻加强防火墙的配置守则,如此一来,你的主机可就能够达到『自我保护』的聪明学习功能啦~ 举例来说,我们可以通过 shell script 去分析『当该封包尝试几次还是连线失败之后,就予以抵挡住该 IP』之类的举动,例如鸟哥写过一个关於抵挡砍站软件的 shell script , 就是用这个想法去达成的呢!

连续命令单一化:

其实,对於新手而言, script 最简单的功能就是:『汇整一些在 command line 下达的连续命令,将他写入 scripts 当中,而由直接运行 scripts 来启动一连串的 command line 命令输入!』例如: 防火墙连续守则 (iptables),启动加载程序的项目 (就是在 /etc/rc.d/rc.local 里头的数据) ,等等都是相似的功能啦! 其实,说穿了,如果不考虑 program 的部分,那么 scripts 也可以想成『仅是帮我们把一大串的命令汇整在一个文件里面, 而直接运行该文件就可以运行那一串又臭又长的命令段!』就是这么简单啦!

简易的数据处理:

由前一章正规表示法的 awk 程序说明中, 你可以发现, awk 可以用来处理简单的数据数据呢!例如薪资单的处理啊等等的。 shell script 的功能更强大,例如鸟哥曾经用 shell script 直接处理数据数据的比对啊, 文字数据的处理啊等等的,撰写方便,速度又快(因为在 Linux 效能较佳),真的是很不错用的啦!

跨平台支持与学习历程较短:

几乎所有的 Unix Like 上面都可以跑 shell script ,连 MS Windows 系列也有相关的 script 模拟器可以用, 此外, shell script 的语法是相当亲和的,看都看的懂得文字 (虽然是英文),而不是机器码, 很容易学习~这些都是你可以加以考量的学习点啊!

上面这些都是你考虑学习 shell script 的特点~此外, shell script 还可以简单的以 vim 来直接编写,实在是很方便的好东西!所以,还是建议你学习一下啦。

不过,虽然 shell script 号称是程序 (program) ,但实际上, shell script 处理数据的速度上是不太够的。因为 shell script 用的是外部的命令与 bash shell 的一些默认工具,所以,他常常会去呼叫外部的函式库,因此,运算速度上面当然比不上传统的程序语言。 所以罗, shell script 用在系统管理上面是很好的一项工具,但是用在处理大量数值运算上, 就不够好了,因为 Shell scripts 的速度较慢,且使用的 CPU 资源较多,造成主机资源的分配不良。还好, 我们通常利用 shell script 来处理服务器的侦测,倒是没有进行大量运算的需求啊!所以不必担心的啦!

第一支 script 的撰写与运行

如同前面讲到的,shell script 其实就是纯文字档,我们可以编辑这个文件,然后让这个文件来帮我们一次运行多个命令, 或者是利用一些运算与逻辑判断来帮我们达成某些功能。所以啦,要编辑这个文件的内容时,当然就需要具备有 bash 命令下达的相关认识。下达命令需要注意的事项在第五章的开始下达命令小节内已经提过,有疑问请自行回去翻阅。 在 shell script 的撰写中还需要用到底下的注意事项:

命令的运行是从上而下、从左而右的分析与运行; 命令的下达就如同第五章内提到的: 命令、选项与参数间的多个空白都会被忽略掉; 空白行也将被忽略掉,并且 [tab] 按键所推开的空白同样视为空白键; 如果读取到一个 Enter 符号 (CR) ,就尝试开始运行该行 (或该串) 命令; 至於如果一行的内容太多,则可以使用『 \[Enter] 』来延伸至下一行; 『 # 』可做为注解!任何加在 # 后面的数据将全部被视为注解文字而被忽略!

如此一来,我们在 script 内所撰写的程序,就会被一行一行的运行。现在我们假设你写的这个程序档名是 /home/dmtsai/shell.sh 好了,那如何运行这个文件?很简单,可以有底下几个方法:

直接命令下达: shell.sh 文件必须要具备可读与可运行 (rx) 的权限,然后: 绝对路径:使用 /home/dmtsai/shell.sh 来下达命令; 相对路径:假设工作目录在 /home/dmtsai/ ,则使用 ./shell.sh 来运行 变量『PATH』功能:将 shell.sh 放在 PATH 指定的目录内,例如: ~/bin/ 以 bash 程序来运行:透过『 bash shell.sh 』或『 sh shell.sh 』来运行

反正重点就是要让那个 shell.sh 内的命令可以被运行的意思啦! 咦!那我为何需要使用 『./shell.sh 』来下达命令?忘记了吗?回去第十一章内的命令搜寻顺序察看一下, 你就会知道原因了!同时,由於 CentOS 默认使用者家目录下的 ~/bin 目录会被配置到 $PATH 内,所以你也可以将 shell.sh 创建在 /home/dmtsai/bin/ 底下 ( ~/bin 目录需要自行配置) 。此时,若 shell.sh 在 ~/bin 内且具有 rx 的权限,那就直接输入 shell.sh 即可运行该脚本程序!

那为何『 sh shell.sh 』也可以运行呢?这是因为 /bin/sh 其实就是 /bin/bash (连结档),使用 sh shell.sh 亦即告诉系统,我想要直接以 bash 的功能来运行 shell.sh 这个文件内的相关命令的意思,所以此时你的 shell.sh 只要有 r 的权限即可被运行喔!而我们也可以利用 sh 的参数,如 -n 及 -x 来检查与追踪 shell.sh 的语法是否正确呢! ^_^

撰写第一支 script

在武侠世界中,不论是那个门派,要学武功要从扫地做起,那么要学程序呢?呵呵,肯定是由『秀出 Hello World!』 这个字眼开始的!OK!那么鸟哥就先写一支 script 给大家瞧一瞧:

[root@www ~]# mkdir scripts; cd scripts [root@www scripts]# vi sh01.sh #!/bin/bash # Program: # This program shows "Hello World!" in your screen. # History: # 2005/08/23 VBird First release PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin export PATH echo -e "Hello World! \a \n" exit 0

在本章当中,请将所有撰写的 script 放置到你家目录的 ~/scripts 这个目录内, 未来比较好管理啦!上面的写法当中,鸟哥主要将整个程序的撰写分成数段,大致是这样:

第一行 #!/bin/bash 在宣告这个 script 使用的 shell 名称: 因为我们使用的是 bash ,所以,必须要以『 #!/bin/bash 』来宣告这个文件内的语法使用 bash 的语法!那么当这个程序被运行时,他就能够加载 bash 的相关环境配置档 (一般来说就是 non-login shell 的 ~/.bashrc), 并且运行 bash 来使我们底下的命令能够运行!这很重要的!(在很多状况中,如果没有配置好这一行, 那么该程序很可能会无法运行,因为系统可能无法判断该程序需要使用什么 shell 来运行啊!)

程序内容的说明: 整个 script 当中,除了第一行的『 #! 』是用来宣告 shell 的之外,其他的 # 都是『注解』用途! 所以上面的程序当中,第二行以下就是用来说明整个程序的基本数据。一般来说, 建议你一定要养成说明该 script 的:1. 内容与功能; 2. 版本资讯; 3. 作者与联络方式; 4. 建档日期;5. 历史纪录 等等。这将有助於未来程序的改写与 debug 呢!

主要环境变量的宣告: 建议务必要将一些重要的环境变量配置好,鸟哥个人认为, PATH 与 LANG (如果有使用到输出相关的资讯时) 是当中最重要的! 如此一来,则可让我们这支程序在进行时,可以直接下达一些外部命令,而不必写绝对路径呢!比较好啦!

主要程序部分 就将主要的程序写好即可!在这个例子当中,就是 echo 那一行啦!

运行成果告知 (定义回传值) 是否记得我们在第十一章里面要讨论一个命令的运行成功与否,可以使用 $? 这个变量来观察~ 那么我们也可以利用 exit 这个命令来让程序中断,并且回传一个数值给系统。 在我们这个例子当中,鸟哥使用 exit 0 ,这代表离开 script 并且回传一个 0 给系统, 所以我运行完这个 script 后,若接著下达 echo $? 则可得到 0 的值喔! 更聪明的读者应该也知道了,呵呵!利用这个 exit n (n 是数字) 的功能,我们还可以自订错误信息, 让这支程序变得更加的 smart 呢!

接下来透过刚刚上头介绍的运行方法来运行看看结果吧!

[root@www scripts]# sh sh01.sh Hello World !

你会看到萤幕是这样,而且应该还会听到『咚』的一声,为什么呢?还记得前一章提到的 printf 吧?用 echo 接著那些特殊的按键也可以发生同样的事情~ 不过, echo 必须要加上 -e 的选项才行!呵呵!在你写完这个小 script 之后,你就可以大声的说:『我也会写程序了』!哈哈! 很简单有趣吧~ ^_^

另外,你也可以利用:『chmod a+x sh01.sh; ./sh01.sh』来运行这个 script 的呢!

撰写 shell script 的良好习惯创建

一个良好习惯的养成是很重要的~大家在刚开始撰写程序的时候,最容易忽略这部分, 认为程序写出来就好了,其他的不重要。其实,如果程序的说明能够更清楚,那么对你自己是有很大的帮助的。

举例来说,鸟哥自己为了自己的需求,曾经撰写了不少的 script 来帮我进行主机 IP 的侦测啊、 登录档分析与管理啊、自动上传下载重要配置档啊等等的,不过,早期就是因为太懒了, 管理的主机又太多了,常常同一个程序在不同的主机上面进行更改,到最后,到底哪一支才是最新的都记不起来, 而且,重点是,我到底是改了哪里?为什么做那样的修改?都忘的一干二净~真要命~

所以,后来鸟哥在写程序的时候,通常会比较仔细的将程序的设计过程给他记录下来,而且还会记录一些历史纪录, 如此一来,好多了~至少很容易知道我修改了哪些数据,以及程序修改的理念与逻辑概念等等, 在维护上面是轻松很多很多的喔!

另外,在一些环境的配置上面,毕竟每个人的环境都不相同,为了取得较佳的运行环境, 我都会自行先定义好一些一定会被用到的环境变量,例如 PATH 这个玩意儿! 这样比较好啦~所以说,建议你一定要养成良好的 script 撰写习惯,在每个 script 的档头处记录好:

script 的功能; script 的版本资讯; script 的作者与联络方式; script 的版权宣告方式; script 的 History (历史纪录); script 内较特殊的命令,使用『绝对路径』的方式来下达; script 运行时需要的环境变量预先宣告与配置。

除了记录这些资讯之外,在较为特殊的程序码部分,个人建议务必要加上注解说明,可以帮助你非常非常多! 此外,程序码的撰写最好使用巢状方式,在包覆的内部程序码最好能以 [tab] 按键的空格向后推, 这样你的程序码会显的非常的漂亮与有条理!在查阅与 debug 上较为轻松愉快喔! 另外,使用撰写 script 的工具最好使用 vim 而不是 vi ,因为 vim 会有额外的语法检验机制,能够在第一阶段撰写时就发现语法方面的问题喔!

简单的 shell script 练习

在第一支 shell script 撰写完毕之后,相信你应该具有基本的撰写功力了。 接下来,在开始更深入的程序概念之前,我们先来玩一些简单的小范例好了。 底下的范例中,达成结果的方式相当的多,建议你先自行撰写看看,写完之后再与鸟哥写的内容比对, 这样才能更加深概念喔!好!不罗唆,我们就一个一个来玩吧!

简单范例

底下的范例在很多的脚本程序中都会用到,而底下的范例又都很简单!值得参考看看喔!

对谈式脚本:变量内容由使用者决定

很多时候我们需要使用者输入一些内容,好让程序可以顺利运行。 简单的来说,大家应该都有安装过软件的经验,安装的时候,他不是会问你『要安装到那个目录去』吗? 那个让使用者输入数据的动作,就是让使用者输入变量内容啦。

你应该还记得在十一章 bash 的时候,我们有学到一个 read 命令吧?现在,请你以 read 命令的用途,撰写一个 script ,他可以让使用者输入:1. first name 与 2. last name, 最后并且在萤幕上显示:『Your full name is: 』的内容:

[root@www scripts]# vi sh02.sh #!/bin/bash # Program: # User inputs his first name and last name. Program shows his full name. # History: # 2005/08/23 VBird First release PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin export PATH read -p "Please input your first name: " firstname # 提示使用者输入 read -p "Please input your last name: " lastname # 提示使用者输入 echo -e "\nYour full name is: $firstname $lastname" # 结果由萤幕输出

将上面这个 sh02.sh 运行一下,你就能够发现使用者自己输入的变量可以让程序所取用,并且将他显示到萤幕上! 接下来,如果想要制作一个每次运行都会依据不同的日期而变化结果的脚本呢?

随日期变化:利用 date 进行文件的创建

想像一个状况,假设我的服务器内有数据库,数据库每天的数据都不太一样,因此当我备份时, 希望将每天的数据都备份成不同的档名,这样才能够让旧的数据也能够保存下来不被覆盖。 哇!不同档名呢!这真困扰啊?难道要我每天去修改 script ?

不需要啊!考虑每天的『日期』并不相同,所以我可以将档名取成类似: backup.2009-02-14.data , 不就可以每天一个不同档名了吗?呵呵!确实如此。那个 2009-02-14 怎么来的?那就是重点啦!接下来出个相关的例子: 假设我想要创建三个空的文件 (透过 touch) ,档名最开头由使用者输入决定,假设使用者输入 filename 好了,那今天的日期是 2009/02/14 , 我想要以前天、昨天、今天的日期来创建这些文件,亦即 filename_20090212, filename_20090213, filename_20090214 ,该如何是好?

[root@www scripts]# vi sh03.sh #!/bin/bash # Program: # Program creates three files, which named by user's input # and date command. # History: # 2005/08/23 VBird First release PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin export PATH # 1. 让使用者输入文件名称,并取得 fileuser 这个变量; echo -e "I will use 'touch' command to create 3 files." # 纯粹显示资讯 read -p "Please input your filename: " fileuser # 提示使用者输入 # 2. 为了避免使用者随意按 Enter ,利用变量功能分析档名是否有配置? filename=${fileuser:-"filename"} # 开始判断有否配置档名 # 3. 开始利用 date 命令来取得所需要的档名了; date1=$(date --date='2 days ago' +%Y%m%d) # 前两天的日期 date2=$(date --date='1 days ago' +%Y%m%d) # 前一天的日期 date3=$(date +%Y%m%d) # 今天的日期 file1=${filename}${date1} # 底下三行在配置档名 file2=${filename}${date2} file3=${filename}${date3} # 4. 将档名创建吧! touch "$file1" # 底下三行在创建文件 touch "$file2" touch "$file3"

上面的范例鸟哥使用了很多在十一章介绍过的概念: 包括小命令『 $(command) 』的取得信息、变量的配置功能、变量的累加以及利用 touch 命令辅助! 如果你开始运行这个 sh03.sh 之后,你可以进行两次运行:一次直接按 [Enter] 来查阅档名是啥? 一次可以输入一些字节,这样可以判断你的脚本是否设计正确喔!

数值运算:简单的加减乘除

各位看官应该还记得,我们可以使用 declare 来定义变量的类型吧? 当变量定义成为整数后才能够进行加减运算啊!此外,我们也可以利用『 $((计算式)) 』来进行数值运算的。 可惜的是, bash shell 里头默认仅支持到整数的数据而已。OK!那我们来玩玩看,如果我们要使用者输入两个变量, 然后将两个变量的内容相乘,最后输出相乘的结果,那可以怎么做?

[root@www scripts]# vi sh04.sh #!/bin/bash # Program: # User inputs 2 integer numbers; program will cross these two numbers. # History: # 2005/08/23 VBird First release PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin export PATH echo -e "You SHOULD input 2 numbers, I will cross them! \n" read -p "first number: " firstnu read -p "second number: " secnu total=$(($firstnu*$secnu)) echo -e "\nThe result of $firstnu x $secnu is ==> $total"

在数值的运算上,我们可以使用『 declare -i total=$firstnu*$secnu 』 也可以使用上面的方式来进行!基本上,鸟哥比较建议使用这样的方式来进行运算:

var=$((运算内容))

不但容易记忆,而且也比较方便的多,因为两个小括号内可以加上空白字节喔! 未来你可以使用这种方式来计算的呀!至於数值运算上的处理,则有:『 +, -, *, /, % 』等等。 那个 % 是取余数啦~举例来说, 13 对 3 取余数,结果是 13=4*3+1,所以余数是 1 啊!就是:

[root@www scripts]# echo $(( 13 % 3 )) 1

这样了解了吧?多多学习与应用喔! ^_^

script 的运行方式差异 (source, sh script, ./script)

不同的 script 运行方式会造成不一样的结果喔!尤其影响 bash 的环境很大呢!脚本的运行方式除了前面小节谈到的方式之外,还可以利用 source 或小数点 (.) 来运行喔!那么这种运行方式有何不同呢?当然是不同的啦!让我们来说说!

利用直接运行的方式来运行 script

当使用前一小节提到的直接命令下达 (不论是绝对路径/相对路径还是 $PATH 内),或者是利用 bash (或 sh) 来下达脚本时, 该 script 都会使用一个新的 bash 环境来运行脚本内的命令!也就是说,使用者种运行方式时, 其实 script 是在子程序的 bash 内运行的!我们在第十一章 BASH 内谈到 export 的功能时,曾经就父程序/子程序谈过一些概念性的问题, 重点在於:『当子程序完成后,在子程序内的各项变量或动作将会结束而不会传回到父程序中』! 这是什么意思呢?

我们举刚刚提到过的 sh02.sh 这个脚本来说明好了,这个脚本可以让使用者自行配置两个变量,分别是 firstname 与 lastname,想一想,如果你直接运行该命令时,该命令帮你配置的 firstname 会不会生效?看一下底下的运行结果:

[root@www scripts]# echo $firstname $lastname sh07.sh 3 'theone haha quot' theone haha 5 'two three four five six' Total parameter number is ==> 2 'five six'

光看结果你就可以知道啦,那个 shift 会移动变量,而且 shift 后面可以接数字,代表拿掉最前面的几个参数的意思。 上面的运行结果中,第一次进行 shift 后他的显示情况是『 one two three four five six』,所以就剩下五个啦!第二次直接拿掉三个,就变成『 two three four five six 』啦! 这样这个案例可以了解了吗?理解了 shift 的功能了吗?

上面这8个例子都很简单吧?几乎都是利用 bash 的相关功能而已~ 不难啦~底下我们就要使用条件判断式来进行一些分别功能的配置了,好好瞧一瞧先~

条件判断式

只要讲到『程序』的话,那么条件判断式,亦即是『 if then 』这种判别式肯定一定要学习的! 因为很多时候,我们都必须要依据某些数据来判断程序该如何进行。举例来说,我们在上头的 sh06.sh 范例中不是有练习当使用者输入 Y/N 时,必须要运行不同的信息输出吗?简单的方式可以利用 && 与 || ,但如果我还想要运行一堆命令呢?那真的得要 if then 来帮忙罗~底下我们就来聊一聊!

利用 if .... then

这个 if .... then 是最常见的条件判断式了~简单的说,就是当符合某个条件判断的时候, 就予以进行某项工作就是了。这个 if ... then 的判断还有多层次的情况!我们分别介绍如下:

单层、简单条件判断式

如果你只有一个判断式要进行,那么我们可以简单的这样看:

if [ 条件判断式 ]; then 当条件判断式成立时,可以进行的命令工作内容; fi 20090401): " date2 # 2. 测试一下,这个输入的内容是否正确?利用正规表示法罗~ date_d=$(echo $date2 |grep '[0-9]\{8\}') # 看看是否有八个数字 if [ "$date_d" == "" ]; then echo "You input the wrong date format...." exit 1 fi # 3. 开始计算日期罗~ declare -i date_dem=`date --date="$date2" +%s` # 退伍日期秒数 declare -i date_now=`date +%s` # 现在日期秒数 declare -i date_total_s=$(($date_dem-$date_now)) # 剩余秒数统计 declare -i date_d=$(($date_total_s/60/60/24)) # 转为日数 if [ "$date_total_s" -lt "0" ]; then # 判断是否已退伍 echo "You had been demobilization before: " $((-1*$date_d)) " ago" else declare -i date_h=$(($(($date_total_s-$date_d*60*60*24))/60/60)) echo "You will demobilize after $date_d days and $date_h hours." fi

瞧一瞧,这支程序可以帮你计算退伍日期呢~如果是已经退伍的朋友, 还可以知道已经退伍多久了~哈哈!很可爱吧~脚本中的 date_d 变量宣告那个 /60/60/24 是来自於一天的总秒数 (24小时*60分*60秒) 。瞧~全部的动作都没有超出我们所学的范围吧~ ^_^ 还能够避免使用者输入错误的数字,所以多了一个正规表示法的判断式呢~ 这个例子比较难,有兴趣想要一探究竟的朋友,可以作一下课后练习题 关於计算生日的那一题喔!~加油!

利用 case ..... esac 判断

上个小节提到的『 if .... then .... fi 』对於变量的判断是以『比对』的方式来分辨的, 如果符合状态就进行某些行为,并且透过较多层次 (就是 elif ...) 的方式来进行多个变量的程序码撰写,譬如 sh09.sh 那个小程序,就是用这样的方式来撰写的罗。 好,那么万一我有多个既定的变量内容,例如 sh09.sh 当中,我所需要的变量就是 "hello" 及空字串两个, 那么我只要针对这两个变量来配置状况就好了,对吧?那么可以使用什么方式来设计呢?呵呵~就用 case ... in .... esac 吧~,他的语法如下:

case $变量名称 in /dev/null && result=0 || result=1 # 开始显示结果是正确的启动 (UP) 还是错误的没有连通 (DOWN) if [ "$result" == 0 ]; then echo "Server ${network}.${sitenu} is UP." else echo "Server ${network}.${sitenu} is DOWN." fi done

上面这一串命令运行之后就可以显示出 192.168.1.1~192.168.1.100 共 100 部主机目前是否能与你的机器连通! 如果你的网域与鸟哥所在的位置不同,则直接修改上头那个 network 的变量内容即可!其实这个范例的重点在 $(seq ..) 那个位置!那个 seq 是连续 (sequence) 的缩写之意!代表后面接的两个数值是一直连续的! 如此一来,就能够轻松的将连续数字带入程序中罗!

最后,让我们来玩判断式加上回圈的功能!我想要让使用者输入某个目录档名, 然后我找出某目录内的档名的权限,该如何是好?呵呵!可以这样做啦~

[root@www scripts]# vi sh18.sh #!/bin/bash # Program: # User input dir name, I find the permission of files. # History: # 2005/08/29 VBird First release PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin export PATH # 1. 先看看这个目录是否存在啊? read -p "Please input a directory: " dir if [ "$dir" == "" -o ! -d "$dir" ]; then echo "The $dir is NOT exist in your system." exit 1 fi # 2. 开始测试文件罗~ filelist=$(ls $dir) # 列出所有在该目录下的文件名称 for filename in $filelist do perm="" test -r "$dir/$filename" && perm="$perm readable" test -w "$dir/$filename" && perm="$perm writable" test -x "$dir/$filename" && perm="$perm executable" echo "The file $dir/$filename's permission is $perm " done

呵呵!很有趣的例子吧~利用这种方式,你可以很轻易的来处理一些文件的特性呢。接下来,让我们来玩玩另一种 for 回圈的功能吧!主要用在数值方面的处理喔!

for...do...done 的数值处理

除了上述的方法之外,for 回圈还有另外一种写法!语法如下:

for (( 初始值; 限制值; 运行步阶 )) do 程序段 done

这种语法适合於数值方式的运算当中,在 for 后面的括号内的三串内容意义为:

初始值:某个变量在回圈当中的起始值,直接以类似 i=1 配置好; 限制值:当变量的值在这个限制值的范围内,就继续进行回圈。例如 i


【本文地址】


今日新闻


推荐新闻


    CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3