文档章节

linux shellScripts-2

拉普兰德
 拉普兰德
发布于 2015/11/19 09:59
字数 2043
阅读 6
收藏 0

利用 case ..... esac 判断

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

case  $变量名称 in   <==关键字为 case ,还有变量前有钱字号
  "第一个变量内容")   <==每个变量内容建议用双引号括起来,关键字则为小括号 )
	程序段	;;            <==每个类别结尾使用两个连续的分号来处理!
  "第二个变量内容")
	程序段	;;
  *)                  <==最后一个变量内容都会用 * 来代表所有其他值
	不包含第一个变量内容与第二个变量内容的其他程序运行段
	exit 1	;;esac                  <==最终的 case 结尾!『反过来写』思考一下!

要注意的是,这个语法以 case (实际案例之意) 为开头,结尾自然就是将 case 的英文反过来写!就成为 esac 罗! 不会很难背啦!另外,每一个变量内容的程序段最后都需要两个分号 (;;) 来代表该程序段落的结束,这挺重要的喔! 至於为何需要有 * 这个变量内容在最后呢?这是因为,如果使用者不是输入变量内容一或二时, 我们可以告知使用者相关的资讯啊!废话少说,我们拿 sh09.sh 的案例来修改一下,他应该会变成这样喔:

[root@www scripts]# vi sh09-2.sh#!/bin/bash
# Program:
# 	Show "Hello" from $1.... by using case .... esac
# History:
# 2005/08/29	VBird	First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH

case $1 in
  "hello")
	echo "Hello, how are you ?"
	;;
  "")
	echo "You MUST input parameters, ex> {$0 someword}"
	;;
  *)   # 其实就相当於万用字节,0~无穷多个任意字节之意!
	echo "Usage $0 {hello}"
	;;
esac

在上面这个 sh09-2.sh 的案例当中,如果你输入『 sh sh09-2.sh test 』来运行, 那么萤幕上就会出现『Usage sh09-2.sh {hello}』的字样,告知运行者仅能够使用 hello 喔~ 这样的方式对於需要某些固定字串来运行的变量内容就显的更加的方便呢! 这种方式你真的要熟悉喔!这是因为系统的很多服务的启动 scripts 都是使用这种写法的, 举例来说,我们 Linux 的服务启动放置目录是在 /etc/init.d/ 当中,我已经知道里头有个 syslog 的服务,我想要重新启动这个服务,可以这样做:

/etc/init.d/syslog restart

重点是那个 restart 啦!如果你使用『 less /etc/init.d/syslog 』去查阅一下,就会看到他使用的是 case 语法, 并且会规定某些既定的变量内容,你可以直接下达 /etc/init.d/syslog , 该 script 就会告知你有哪些后续接的变量可以使用罗~方便吧! ^_^

一般来说,使用『 case $变量 in 』这个语法中,当中的那个『 $变量 』大致有两种取得的方式:

  • 直接下达式:例如上面提到的,利用『 script.sh variable 』 的方式来直接给予 $1 这个变量的内容,这也是在 /etc/init.d 目录下大多数程序的设计方式。

  • 互动式:透过 read 这个命令来让使用者输入变量的内容。

这么说或许你的感受性还不高,好,我们直接写个程序来玩玩:让使用者能够输入 one, two, three , 并且将使用者的变量显示到萤幕上,如果不是 one, two, three 时,就告知使用者仅有这三种选择。

[root@www scripts]# vi sh12.sh#!/bin/bash
# Program:
#	This script only accepts the flowing parameter: one, two or three.
# History:
# 2005/08/29	VBird	First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH

echo "This program will print your selection !"
# read -p "Input your choice: " choice # 暂时取消,可以替换!# case $choice in                      # 暂时取消,可以替换!case $1 in                             # 现在使用,可以用上面两行替换!
  "one")
	echo "Your choice is ONE"
	;;
  "two")
	echo "Your choice is TWO"
	;;
  "three")
	echo "Your choice is THREE"
	;;
  *)
	echo "Usage $0 {one|two|three}"
	;;
esac

此时,你可以使用『 sh sh12.sh two 』的方式来下达命令,就可以收到相对应的回应了。 上面使用的是直接下达的方式,而如果使用的是互动式时,那么将上面第 10, 11 行的 "#" 拿掉, 并将 12 行加上注解 (#),就可以让使用者输入参数罗~这样是否很有趣啊?

利用 function 功能

什么是『函数 (function)』功能啊?简单的说,其实, 函数可以在 shell script 当中做出一个类似自订运行命令的东西,最大的功能是, 可以简化我们很多的程序码~举例来说,上面的 sh12.sh 当中,每个输入结果 one, two, three 其实输出的内容都一样啊~那么我就可以使用 function 来简化了! function 的语法是这样的:

function fname() {
	程序段}

那个 fname 就是我们的自订的运行命令名称~而程序段就是我们要他运行的内容了。 要注意的是,因为 shell script 的运行方式是由上而下,由左而右, 因此在 shell script 当中的 function 的配置一定要在程序的最前面, 这样才能够在运行时被找到可用的程序段喔!好~我们将 sh12.sh 改写一下,自订一个名为 printit 的函数来使用喔:

[root@www scripts]# vi sh12-2.sh#!/bin/bash
# Program:
#	Use function to repeat information.
# History:
# 2005/08/29	VBird	First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH

function printit(){
	echo -n "Your choice is "     # 加上 -n 可以不断行继续在同一行显示}

echo "This program will print your selection !"
case $1 in
  "one")	printit; echo $1 | tr 'a-z' 'A-Z'  # 将参数做大小写转换!
	;;
  "two")	printit; echo $1 | tr 'a-z' 'A-Z'
	;;
  "three")	printit; echo $1 | tr 'a-z' 'A-Z'
	;;
  *)
	echo "Usage $0 {one|two|three}"
	;;
esac

以上面的例子来说,鸟哥做了一个函数名称为 printit ,所以,当我在后续的程序段里面, 只要运行 printit 的话,就表示我的 shell script 要去运行『 function printit .... 』 里面的那几个程序段落罗!当然罗,上面这个例子举得太简单了,所以你不会觉得 function 有什么好厉害的, 不过,如果某些程序码一再地在 script 当中重复时,这个 function 可就重要的多罗~ 不但可以简化程序码,而且可以做成类似『模块』的玩意儿,真的很棒啦!

function 也是拥有内建变量的~他的内建变量与 shell script 很类似, 函数名称代表示 $0 ,而后续接的变量也是以 $1, $2... 来取代的~ 这里很容易搞错喔~因为『 function fname() { 程序段 } 』内的 $0, $1... 等等与 shell script 的 $0 是不同的。以上面 sh12-2.sh 来说,假如我下达:『 sh sh12-2.sh one 』 这表示在 shell script 内的 $1 为 "one" 这个字串。但是在 printit() 内的 $1 则与这个 one 无关。 我们将上面的例子再次的改写一下,让你更清楚!

[root@www scripts]# vi sh12-3.sh#!/bin/bash
# Program:
#	Use function to repeat information.
# History:
# 2005/08/29	VBird	First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH

function printit(){
	echo "Your choice is $1"   # 这个 $1 必须要参考底下命令的下达}

echo "This program will print your selection !"
case $1 in
  "one")	printit 1  # 请注意, printit 命令后面还有接参数!
	;;
  "two")	printit 2
	;;
  "three")	printit 3
	;;
  *)
	echo "Usage $0 {one|two|three}"
	;;
esac

在上面的例子当中,如果你输入『 sh sh12-3.sh one 』就会出现『 Your choice is 1 』的字样~ 为什么是 1 呢?因为在程序段落当中,我们是写了『 printit 1 』那个 1 就会成为 function 当中的 $1 喔~ 这样是否理解呢?


© 著作权归作者所有

共有 人打赏支持
拉普兰德
粉丝 1
博文 35
码字总数 51254
作品 0
郑州
程序员
hadoop+zookeeper集群高可用搭建

Hadoop集群搭建步骤 1. 架构图 2. 准备5台机器 centosa: 192.168.42.128 centosb: 192.168.42.129 centosc: 192.168.42.130 centosd: 192.168.42.133 centose: 192.168.42.134 namenode: ce......

lvzhl
2016/12/12
556
0
2、利用expect代替人工进行人机交互,从而实现自动化部署

1:需求描述 开发shell脚本,实现对局域网中的N台节点批量自动下载、安装jdk 2:系统设计思路 1.)需要将一台机器作为HTTP服务器,以便集群中的机器从中下载jdk 2.)创建一个脚本install.sh,...

刘付kin
2016/11/29
7
0
OS Recommendations【推荐操作系统】

推荐操作系统(内容提要) 1.Ceph Dependencies(Ceph的依赖) 1.1 Linux Kernel(Linux内核) 1.2 glibc 2.Platforms(平台) 2.1 Dumpling(0.67) 2.2 Cuttlefish(0.61) 2.3 Bobtail(0...

天空冰雨
2015/03/25
0
0
亚马逊Linux发行版,竟然不和AWS捆绑了?

  【IT168 资讯】可以说,亚马逊网络服务(AWS)从开始运营起,就是亚马逊自己的Linux操作系统在一直为其提供支持。最初,Amazon Linux只是Red Hat社区Fedora Linux的优化版本,更适应于AWS...

it168网站
01/05
0
0
MintBox Mini 2计算机预装Linux Mint 19即将·发货

MintBox Mini 2计算机预装Linux Mint 19即将·发货 Ronny 23分钟前暂无评论 阅读 14 次 导读 Linux Mint项目负责人Clement Lefebvre今天宣布,MintBox Mini 2和MintBox Mini 2 Pro计算机现已...

Ronny
07/12
0
0

没有更多内容

加载失败,请刷新页面

加载更多

麒麟AI首席科学家现世

8月31日,华为发布了新一代顶级人工智能手机芯片麒麟980,成为全球首款7nm工艺手机芯片,AI方面也实现飞跃,支持人脸识别、物体识别、物体检测、图像分割、智能翻译等。 虽然如今人人都在热议...

问题终结者
昨天
1
0
告警系统主脚本、告警系统配置文件、告警系统监控项目

告警系统主脚本 main.sh内容 #!/bin/bash#Written by aming.# 是否发送邮件的开关export send=1# 过滤ip地址export addr=`/sbin/ifconfig |grep -A1 "ens33: "|awk '/inet/ {pr...

芬野de博客
昨天
2
0
MySQL autocommit探究

-- sessionA:tx_isolation=REPEATABLE-READmysql> select connection_id();+-----------------+| connection_id() |+-----------------+| 28 |+-----------------+......

安小乐
昨天
7
0
c++多线程锁 Mutex  自动判断死锁

c++多线程锁可以使用absl::Mutex std::mutex这两种,下面是demo代码。 使用absl:Mutex的时候打印: [mutex.cc : 1338] RAW: Cycle: [mutex.cc : 1352] RAW: mutex@0x683b68 stack: @ 0x43856......

青黑
昨天
3
0
Blockathon2018(成都站)比赛落幕,留给我们这些区块链应用思考

9月14日,HiBlock区块链社区主办的第二届Blockathon在成都菁融国际广场成功举行,30名参赛者分为5支队伍在48小时内完成区块链项目的创意、开发及路演,经过紧张的开发及现场评选,最终币托(...

HiBlock
昨天
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部